Перенаправление и пайпинг – две полезные функции в скриптах 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) перед оператором перенаправления, чтобы перенаправить вывод в файл

📜 Bash – как перенаправить стандартный вывод (stdout) и стандартную ошибку (stderr ) в один и тот же файл

$ 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.

 

Поделитесь статьей:

Добавить комментарий