Перенаправление в Bash
Суперпользователь Linux должен хорошо разбираться в каналах и перенаправлении в Bash. Это важный компонент системы, который часто бывает полезен в области системного администрирования Linux.
Когда вы запускаете команду типа ls, catи т. д., вы получаете некоторый вывод на терминал. Если вы напишете неверную команду, передадите неправильный флаг или неверный аргумент командной строки, вы получите вывод ошибки на терминал. В обоих случаях вам предоставляется некоторый текст. Вам может показаться, что это «просто текст», но система воспринимает этот текст по-другому. Этот идентификатор известен как дескриптор файла (fd).
В Linux существует три файловых дескриптора: STDIN (0); СТАНДАРТНЫЙ ВЫВОД (1) и СТАНДЕРР (2).
STDIN (fd: 0): управляет вводом в терминале.
STDOUT (fd: 1): управляет выводом текста в терминал.
STDERR (fd: 2): управляет текстом ошибки в терминале.
Разница между каналами и перенаправлениями
И каналы , и перенаправления перенаправляют потоки (file descriptor)выполняемого процесса. Основное отличие состоит в том, что перенаправления связаны с files streamотправкой выходного потока в файл или отправкой содержимого данного файла во входной поток процесса.
С другой стороны, канал соединяет две команды, отправляя выходной поток первой во входной поток второй. без указания каких-либо переработок.
Перенаправление в Bash
STDIN (стандартный ввод)
Когда вы вводите некоторый входной текст для команды, которая его запрашивает, вы фактически вводите текст в файловый дескриптор STDIN . Запустите catкоманду без каких-либо аргументов командной строки. Может показаться, что процесс остановился, но на самом деле он catзапрашивает STDIN . catэто простая программа, которая печатает текст, переданный в STDIN . Однако вы можете расширить вариант использования, перенаправив ввод на команды, принимающие STDIN .
Пример с cat:
cat << EOF
Hello World!
How are you?
EOFЭто просто напечатает предоставленный текст на экране терминала:
Hello World!
How are you?То же самое можно сделать и с другими командами, которые принимают входные данные через STDIN. Например wc:
wc -l << EOF
Hello World!
How are you?
EOFФлаг -lс wcподсчитывает количество строк. Этот блок кода bash выведет количество строк на экран терминала:
2STDOUT (стандартный вывод)
Обычный текст без ошибок на экране вашего терминала печатается через файловый дескриптор STDOUT . STDOUT команды можно перенаправить в файл таким образом, что вывод команды записывается в файл, а не печатается на экране терминала . Это делается просто с помощью операторов >и >>.
Пример:
echo "Hello World!" > file.txtСледующая команда не будет печатать «Hello World» на экране терминала, вместо этого она создаст файл с именем file.txtи запишет в него строку «Hello World». Это можно проверить, выполнив catкоманду над file.txtфайлом.
cat file.txtОднако каждый раз, когда вы несколько раз перенаправляете STDOUT любой команды в один и тот же файл, существующее содержимое файла будет удалено для записи нового.
Пример:
echo "Hello World!" > file.txt
echo "How are you?" > file.txtПри запуске catфайла file.txt:
cat file.txtВы получите только вопрос «Как дела?» напечатана строка.
How are you?Это связано с тем, что строка «Hello World» была перезаписана. Такого поведения можно избежать с помощью >>оператора.
Приведенный выше пример можно записать так:
echo "Hello World!" > file.txt
echo "How are you?" >> file.txtЗапустив catфайл file.txt, вы получите желаемый результат.
Hello World!
How are you?В качестве альтернативы оператор перенаправления для STDOUT также может быть записан как 1>. Нравиться,
echo "Hello World!" 1> file.txtSTDERR (стандартная ошибка)
Текст ошибки на экране терминала выводится через STDERR команды. Например:
ls --helloбудет выдавать сообщения об ошибках. Это сообщение об ошибке является STDERR команды.
STDERR можно перенаправить с помощью 2>оператора.
ls --hello 2> error.txtЭта команда перенаправит сообщение об ошибке в error.txtфайл и запишет его в него. Это можно проверить, выполнив catкоманду над error.txtфайлом.
Вы также можете использовать 2>>оператор для STDERR так же, как вы использовали >>для STDOUT .
Сообщения об ошибках в сценариях Bash иногда могут быть нежелательными. Вы можете игнорировать их, перенаправив сообщение об ошибке в /dev/nullфайл. /dev/null— это псевдоустройство, которое принимает текст, а затем немедленно его отбрасывает.
Приведенный выше пример можно записать следующим образом, чтобы полностью игнорировать текст ошибки:
ls --hello 2> /dev/nullКонечно, вы можете перенаправить как STDOUT , так и STDERR для одной и той же команды или сценария.
./install_package.sh > output.txt 2> error.txtОба они также могут быть перенаправлены в один и тот же файл.
./install_package.sh > file.txt 2> file.txtСуществует также более короткий способ сделать это.
./install_package.sh > file.txt 2>&1Трубопроводы
До сих пор мы видели, как перенаправить STDOUT , STDIN и STDOUT в файл и из файла. Чтобы объединить выходные данные программы (команды) с входными данными другой программы (команды), вы можете использовать вертикальную черту |.
Пример:
ls | grep ".txt"Эта команда выведет список файлов в текущем каталоге и передаст вывод grepкоманде, которая затем отфильтрует вывод, чтобы отображать только файлы, содержащие строку «.txt».
Синтаксис:
[time [-p]] [!] command1 [ | or |& command2 ] …Вы также можете создавать произвольные цепочки команд, соединяя их вместе для достижения мощного результата.
В этом примере создается список всех пользователей, которым принадлежит файл в данном каталоге, а также количество файлов и каталогов, которыми они владеют:
ls -l /projects/bash_scripts | tail -n +2 | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | sort | uniq -cВыход:
8 anne
34 harry
37 tina
18 ryanHereDocument
Символ <<можно использовать для создания временного файла [heredoc] и перенаправления из него в командной строке.
COMMAND << EOF
ContentOfDocument
...
...
EOFОбратите внимание, что здесь EOFпредставлен разделитель (конец файла) heredoc. Фактически, мы можем использовать любое буквенно-цифровое слово вместо него для обозначения начала и конца файла. Например, это действительный документ:
cat << randomword1
This script will print these lines on the terminal.
Note that cat can read from standard input. Using this heredoc, we can
create a temporary file with these lines as it's content and pipe that
into cat.
randomword1По сути, это будет выглядеть так, как будто содержимое heredoc передается по конвейеру в команду. Это может сделать сценарий очень чистым, если в программу необходимо передать несколько строк.
Далее мы можем прикрепить еще трубы, как показано:
cat << randomword1 | wc
This script will print these lines on the terminal.
Note that cat can read from standard input. Using this heredoc, we can
create a temporary file with these lines as it's content and pipe that
into cat.
randomword1Кроме того, внутри heredocs можно использовать предопределенные переменные.
HereString
Herstrings очень похожи на heredocs, но используют файлы <<<. Они используются для однострочных строк, которые необходимо передать в какую-либо программу. Это выглядит чище, чем heredocs, поскольку нам не нужно указывать разделитель.
wc <<<"this is an easy way of passing strings to the stdin of a program (here wc)"Как и Heredoc, строки могут содержать переменные.
Last updated