Перенаправление и пайпинг – две полезные функции в скриптах bash, которые часто используют сисадмины и девопсеры.
В этом руководстве мы обсудим, что такое перенаправление Bash и как работать с перенаправлением в Bash с помощью примеров команд.
Прежде чем понять, как работает перенаправление, важно узнать, что такое файловый дескриптор.
🐧 Как запускать команды Bash в фоновом режиме в Linux
Что такое дескриптор файла?
Когда вы открываете файл в Linux, каждому файлу присваивается целое число, и эта информация хранится в ядре.
Таким образом, ядро знает, какие файлы открыты и какой процесс открыл эти файлы.
Присвоенный номер Integer – это то, что мы называем дескриптором файла (сокращенно FD).
По умолчанию каждая программа запускается с тремя файловыми дескрипторами.
- FD 0 -> Стандартный вход(stdin) -> клавиатура
- FD 1 -> Стандартный вывод(Stdout) -> дисплей(терминал)
- FD 2 -> Стандартная ошибка(Stderr) -> Дисплей(терминал)
Вы можете увидеть дескрипторы файлов в каталоге /dev:
$ ls -l /dev/std* lrwxrwxrwx 1 root root 15 Aug 27 21:32 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 Aug 27 21:32 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 Aug 27 21:32 /dev/stdout -> /proc/self/fd/1
Stdin (FD0) получает ввод с клавиатуры. stdout (FD1) и stderr (FD2) отправляются на терминал.
При использовании пайпов и перенаправлений вы можете изменить способ передачи входных данных, а также выходных данных и ошибок.
Перенаправление вывода в файл
Как было сказано ранее, вывод (stdout) и ошибки (stderr) любой программы отправляются на терминал.
Вы можете использовать оператор перенаправления “>” для записи stdout и stderr в файл.
Посмотрите на приведенный ниже пример.
Я выполняю команду uname -mrs и перенаправляю вывод в файл с именем uname.log.
$ uname -mrs > uname.log
$ cat uname.log Linux 5.10.0-8-amd64 x86_64
Внимание: При использовании оператора “>”, если файл недоступен, он будет создан. А если файл уже существует, он будет заменен новым содержимым.
Вы также можете использовать номер дескриптора файла для stdout(1) перед оператором перенаправления, чтобы перенаправить вывод в файл
$ uname -mrs 1> uname.log
Как я уже упоминал, одинарный оператор перенаправления (>) будет заменять содержимое файла, только если файл уже существует.
Однако, если вы хотите добавить содержимое вместо перезаписи в тот же файл, используйте двойной оператор перенаправления (т.е. >>).
Вы также можете использовать здесь дескриптор файла stdout(1).
$ whoami >> uname.log
$ echo $SHELL 1>> uname.log
$ cat uname.log Linux 5.10.0-8-amd64 x86_64 itisgood /bin/bash
Как работать с Stderr
Каждая программа генерирует как вывод, так и ошибку, и оба вывода отправляются на терминал.
Во многих случаях вы можете захотеть либо проигнорировать ошибку, либо изолировать ее и перенаправить в отдельный файл для устранения неполадок.
Давайте рассмотрим простой пример выполнения команды ls, чтобы увидеть, как это работает.
Я пытаюсь перечислить два файла, из которых присутствует только один.
Я получаю и ошибку, и вывод в терминале, как я уже говорил.
$ ls -l uname.log u1.log ls: cannot access 'u1.log': No such file or directory -rw-r--r-- 1 itisgood itisgood 48 Aug 27 07:37 uname.log
Я снова выполняю ту же команду ls, но на этот раз перенаправляю вывод в файл.
Как видно из вывода, оператор > перенаправляет stdout(1) в файл, но stderr(2) отправляется на терминал.
$ ls -l uname.log u1.log > ls.op ls: cannot access 'u1.log': No such file or directory
Для перенаправления stderr в файл используйте оператор “2>”.
Обязательно использовать дескриптор файла для stderr(2) перед оператором перенаправления >, который будет отправлять ошибку только в файл.
$ ls -l uname.log u1.log > ls.op 2> ls.err
$ cat ls.err ls: cannot access 'u1.log': No such file or directory
Теперь stdout и stderr записываются в отдельные файлы.
Вы также можете отправить stdout и stderr в один файл.
$ ls -l uname.log u1.log 1> ls.op 2> ls.op
Начиная с bash 4.4, вы также можете использовать знак &> для перенаправления и stdout, и stderr в один файл.
$ ls -l uname.log u1.log &> ls.op
Что такое /dev/null?
Null – это специальный символьный файл, который принимает входные данные, отбрасывает их и не производит никакого вывода.
Проще говоря, null отбрасывает все, что вы перенаправляете в него.
$ ls -l /dev/null crw-rw-rw- 1 root root 1, 3 Aug 27 06:01 /dev/null
Почему нуль имеет значение при перенаправлении?
Вы можете задаться этим вопросом
. В некоторых случаях вы можете не выводить и не сохранять stdout или stderr.
В этом случае вы можете перенаправить либо stdout, либо stderr в /dev/null, что приведет к отбрасыванию потока ввода.
$ date > /dev/null $ date 1> /dev/null # Stdout to Null $ dateee 2> /dev/null # WRONG COMMAND, Stderr to Null $ date &> /dev/null # Stdout/Stderr to Null
Перенаправление ввода в Bash
Подобно тому, как вы перенаправляете вывод и ошибку в файл, вы также можете передавать входные данные команде с помощью оператора перенаправления ввода (<).
Давайте начнем с простой программы подсчета слов.
Здесь я перенаправляю содержимое файла itisgood.txt в программу подсчета слов, чтобы найти количество строк.
$ wc -l < itisgood.txt 10
Вы также можете передать дескриптор файла stdin (0) при перенаправлении ввода.
$ wc -l 0< itisgood.txt 10
Вы можете комбинировать операторы перенаправления ввода и вывода, как показано ниже.
$ wc -l < itisgood.txt &> /tmp/wc.op
$ cat /tmp/wc.op 10
Перенаправление ввода будет использоваться вместе с циклом while для чтения содержимого файла построчно.
Взгляните на приведенный ниже пример.
Я передаю файл /etc/passwd в качестве входных данных команде while.
Здесь команда read прочитает строку за строкой и сохранит ее в переменной VAL, а далее в цикле будет записано условие для проверки, доступен ли пользователь.
while read VAL; do NAME=$(echo $VAL | awk -F ":" '/1/ {print $1}' ) if [[ $NAME = "karthick" ]] then echo "User spotted" fi done < /etc/passwd
Замените “karthick” в приведенном выше коде на имя пользователя вашей системы.
Сохраните файл и закройте его.
Это не самый оптимальный способ решения задачи поиска пользователя, но для демонстрационных целей сойдет.
Теперь сделайте скрипт исполняемым и запустите его:
$ chmod +x itisgood.sh
$ ./itisgood.sh User spotted
Заключение
В этом руководстве мы изучили несколько важных концепций сценариев, таких как что такое перенаправление Bash, что такое дескриптор файла, как перенаправить вывод в файл, как работать с stderr, что такое /dev/null и как он используется в перенаправлении Bash, и, наконец, мы завершили руководство перенаправлением ввода в Bash.