Треки
/
Bash
Bash
/
Салабус
/
Перенаправлення
Пе

Перенаправлення у Bash

{one: "1 вправа", few: "%{count} вправи", many: "%{count} вправ", other: "%{count} вправи"}

Про концепцію Перенаправлення

У світі інтерфейсу командного рядка програми часто взаємодіють із трьома стандартними потоками даних:

  1. Стандартний ввід (stdin): звідки програма отримує вхідні дані (зазвичай із клавіатури).
  2. Стандартні вихідні дані (stdout): куди програма надсилає свої звичайні вихідні дані (зазвичай на екран термінала).
  3. Стандартні повідомлення про помилки (stderr): куди програма надсилає повідомлення про помилки (зазвичай на екран термінала).

Пригадаймо, що ми познайомилися з ними в розділі Конвеєри та списки команд.

Note

Конвеєри можна вважати різновидом перенаправлення: стандартні вихідні дані однієї програми надсилаються безпосередньо на стандартний ввід іншої. Конвеєри ми вже розглянули. Тут ми розглянемо перенаправлення до файлів і з файлів.

Перенаправлення в оболонці - це потужний механізм, який дає змогу змінювати призначення цих потоків. Замість того щоб програма читала з клавіатури чи писала на екран, ми можемо перенаправити ввід із файлу або надіслати вихідні дані до файлу. Це дає чималу гнучкість і контроль над тим, як програми взаємодіють із даними.

Основні оператори перенаправлення

Ось найпоширеніші оператори перенаправлення та те, що вони роблять:

> (перенаправлення вихідних даних)

  • Призначення: перенаправити стандартні вихідні дані (stdout) команди до файлу.

  • Поведінка:

    • Якщо файл не існує, він створюється.
    • Якщо файл існує, його вміст перезаписується.
  • Приклад:

    # Sends the output of 'ls -l' to 'file_listing.txt'
    ls -l > file_listing.txt
    
Caution

Перенаправлення виконується до запуску команди. Це означає, що не можна перенаправляти до того самого файлу, з якого треба читати.

date > date.txt         # populate the file with the current date
cat date.txt > date.txt # 'date.txt' is now empty!

У другій команді наведеного прикладу

  1. Спершу Bash обрізає файл, указаний у перенаправленні. Це знищує попередній вміст, залишаючи порожній файл.
  2. Потім bash читає щойно спорожнений файл.
  3. Далі bash записує вміст (тобто нічого) назад у файл.

>> (дописування вихідних даних)

  • Призначення: дописати стандартні вихідні дані (stdout) команди в кінець файлу.

  • Поведінка:

    • Якщо файл не існує, він створюється.
    • Якщо файл існує, вихідні дані додаються в кінець файлу.
  • Приклад:

    # Adds "Another line" to the end of the file
    echo "Another line" >> file_listing.txt
    

< (перенаправлення вводу)

  • Призначення: перенаправити стандартний ввід (stdin) команди з файлу.

  • Поведінка: команда читає вхідні дані із зазначеного файлу, а не з клавіатури.

  • Приклад:

    # 'tr' reads from 'lowercase.txt' and
    # output is redirected to 'uppercase.txt'
    tr 'a-z' 'A-Z' < lowercase.txt > uppercase.txt
    

2> (перенаправлення помилок):

  • Призначення: перенаправити стандартні повідомлення про помилки (stderr) команди до файлу.
  • Поведінка: повідомлення про помилки надсилаються до зазначеного файлу, а не на термінал.
  • Приклад:
    # Error message from 'rm' is sent to 'error_log.txt'
    rm non_existent_file 2> error_log.txt
    

Стандартні повідомлення про помилки можна дописати до файлу за допомогою 2>>.

Додаткові перенаправлення

Існують також перенаправлення, які можуть обʼєднати і stdin, і stderr. Докладніше описано в посібнику.

/dev/null

/dev/null - це спеціальний файл, який

  • порожній, коли ми читаємо з нього, і
  • відкидає всі дані, записані до нього.

Іноді його називають «бітовим кошиком». Він корисний, щоб заглушити вихідні дані або помилки.

some_command > /dev/null  # Discards stdout
some_command 2> /dev/null # Discards stderr

# Using /dev/null as input will prevent the command
# from reading data from the keyboard
some_command < /dev/null

Поєднання перенаправлень

Можна вказати кілька перенаправлень одразу.

some_command < input.txt > output.txt 2> error.txt

Перенаправлення можна скопіювати.

# send stderr to the same destination as stdout
some_command > output.txt 2>&1

Коли ми бачимо 2>&1, читаймо це так: «перенаправити stderr туди, куди наразі вказує stdout». Bash обробляє інструкції перенаправлення строго зліва направо, а отже, ми можемо зробити так:

# redirect stdout to 'output1.txt'
# redirect stderr to the same place
# then change stdout to 'output2.txt'
some_command > output1.txt 2>&1 > output2.txt
Advanced

Файлові дескриптори

У контексті програмування оболонки та операційних систем на кшталт Linux/Unix файловий дескриптор (FD) - це невідʼємне ціле число, яке слугує ідентифікатором або посиланням на відкритий файл чи ресурс вводу-виводу (I/O, ввід/вивід). Уявімо це як мітку або номер-посилання, який операційна система використовує, щоб відстежувати відкриті файли та потоки даних.

Числа, які ми бачимо ліворуч від перенаправлень, - це файлові дескриптори.

Стандартним потокам вводу-виводу відведено перші 3 файлові дескриптори:

  • стандартний ввід - FD 0
  • стандартні вихідні дані - FD 1
  • стандартні повідомлення про помилки - FD 2

Нові файлові дескриптори можна задати або створити за допомогою команди exec та операторів перенаправлення.

# create FD 3 as a copy of stdout
exec 3>&1
# send stdout to a log file
exec > log.txt

# then redirect both stdout and file descriptor 3
echo "some debug message" >&3  # displayed in the terminal
some_command  2>&1 # stdout and stderr send to 'log.txt'

Цей прийом може здатися досить заплутаним, але він стає в пригоді, коли наш скрипт запускає якийсь інший програмний пакет, і той автоматично перехоплює стандартні вихідні дані. Команда bats, яку використовують для запуску модульних тестів у цьому треку, працює саме так: bats перехоплює stdout і stderr тесту, але повідомлення для налагодження, надіслані до FD 3, усе одно показуються на терміналі.

Підсумок

Чим корисне перенаправлення?

  • Збереження вихідних даних: зберігати результати команди, щоб переглянути чи обробити їх пізніше.
  • Журналювання: перехоплювати повідомлення про помилки для налагодження.
  • Автоматизація: зчіплювати команди в ланцюжки, використовуючи вихідні дані однієї як вхідні дані для іншої.
  • Фільтрування: відкидати непотрібні вихідні дані.
  • Пакетна обробка: обробляти дані з файлів замість того, щоб вводити їх вручну.
  • Написання скриптів: перенаправлення потрібні для написання надійних скриптів оболонки.

Перенаправлення в оболонці дають змогу тонко керувати тим, як програми взаємодіють із даними, що дозволяє будувати складні робочі процеси та ефективно керувати інформацією.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці