Перенаправление в 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 выведет количество строк на экран терминала:

2

STDOUT (стандартный вывод)

Обычный текст без ошибок на экране вашего терминала печатается через файловый дескриптор 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.txt

STDERR (стандартная ошибка)

Текст ошибки на экране терминала выводится через 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 ryan

HereDocument

Символ <<можно использовать для создания временного файла [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