С чего начать Первые шаги трек · 15 ступеней
Linux Labs

Перенаправление вывода и конвейеры

6 мин Ubuntu 24.04 · Bash 5.2

Оболочка направляет ввод и вывод команды в файл или в другую команду: >, >>, 2>&1, /dev/null, конвейер |.

Шпаргалка

10 команд Версия для печати
  • cmd > out.txt вывод в файл (перезаписать)
  • cmd >> out.txt вывод в конец файла
  • cmd 2> err.txt ошибки в файл
  • cmd > all.txt 2>&1 вывод и ошибки в один файл
  • cmd &> all.txt то же короче (bash)
  • cmd 2>/dev/null выбросить ошибки
  • cmd < in.txt ввод из файла
  • cmd1 | cmd2 вывод cmd1 — на ввод cmd2
  • cmd 2>&1 | less в конвейер вместе с ошибками
  • cmd | tee out.txt и на экран, и в файл

Обзор

У каждой программы с запуска открыты три потока. Номер потока — файловый дескриптор:

Поток Что это
0 — stdin ввод: по умолчанию клавиатура
1 — stdout обычный вывод: по умолчанию экран
2 — stderr ошибки и предупреждения: тоже экран

Перенаправление — указание оболочке подключить поток к файлу или к другой команде. Его выполняет оболочка до запуска команды, сама команда о нём не знает. Поэтому ошибки видны на экране, даже когда вывод ушёл в файл:

text
student@ubuntu:~$ ls /etc/hostname /nope > out.txt
ls: cannot access '/nope': No such file or directory
student@ubuntu:~$ cat out.txt
/etc/hostname

2>&1 значит «поток 2 туда же, куда сейчас идёт поток 1». Конвейер | соединяет stdout одной команды со stdin следующей; все звенья работают одновременно.

Рецепты

7

Вывод и ошибки — в разные файлы

bash
./backup.sh > backup.log 2> backup.err

Порядок 2>&1 имеет значение

bash
cmd > all.txt 2>&1     # оба потока в файл
cmd 2>&1 > all.txt     # в файл — только вывод, ошибки на экран

Оболочка читает перенаправления слева направо. Во второй строке 2>&1 копирует то, куда stdout указывал в тот момент, — экран.

Обработать вывод цепочкой команд

bash
sudo grep 'Failed password' /var/log/auth.log | wc -l
ps -eo rss,comm | sort -rn | head -n 5   # пять процессов по памяти
du -sh /var/log/* 2>/dev/null | sort -rh | head

Каждое звено делает одну вещь: grep отбирает, sort упорядочивает, wc считает, head обрезает. Такие команды — читают ввод, печатают обработанный текст — называют фильтрами.

Записать в файл, которому нужен root

bash
echo '127.0.0.1 app.local' | sudo tee -a /etc/hosts

sudo cmd > /etc/файл не сработает: перенаправление делает твоя оболочка без прав root. tee запускается через sudo и пишет сам.

Многострочный ввод прямо в команду

bash
cat > app.conf <<'EOF'
port = 8080
log = /var/log/app.log
EOF

Очистить журнал, не удаляя файл

bash
: > /var/log/app.log         # длина 0, файл и владелец на месте
sudo truncate -s 0 /var/log/app.log   # то же для файла root

Если процесс держит журнал открытым, rm не вернёт место, а обнуление вернёт.

Узнать, какое звено конвейера упало

bash
false | true
echo "${PIPESTATUS[@]}"      # 1 0 — коды каждого звена
set -o pipefail              # в скриптах: ошибка любого звена видна

Неполадки

6

Permission denied при sudo … > файл

Файл открывает твоя оболочка, а не sudo. Используй | sudo tee файл (или tee -a, чтобы дописать).

bash: $F: ambiguous redirect

В имени файла из переменной пробел, или переменная пуста. Бери переменную в кавычки: > "$F", и проверь, что она задана.

bash: out.txt: cannot overwrite existing file

Включён режим noclobber (set -o noclobber), он запрещает > поверх файла. Перезаписать явно — >|, выключить режим — set +o noclobber.

Ошибки не попали в файл

> перенаправляет только stdout. Добавь 2>&1 после > файл или используй &>.

grep в конвейере не находит текст ошибки

Ошибка ушла в stderr, а конвейер передаёт только stdout. Передай оба потока: cmd 2>&1 | grep текст.

После sort file > file файл пуст

Оболочка обнулила file для записи до того, как sort его прочитал. Пиши в новый файл и переименуй через mv; у sort для этого есть -o file.

Опасно

2

> перезаписывает без вопроса

Одна стрелка вместо двух — и журнал или конфиг заменён одной строкой. Для дописывания всегда >>. В интерактивной оболочке можно включить защиту: set -o noclobber.

2>/dev/null прячет причину

Подавленные ошибки удобно убирать из вывода find /, но в скриптах и при диагностике они и есть ответ. Сначала прочитай ошибку, потом решай, глушить ли её.

Термины

7
стандартный ввод standard input
Входной поток с файловым дескриптором 0; источником может быть терминал, файл или канал. Ещё встречается в: /proc: процессы и ядро в виде файлов
стандартный вывод standard output
Основной выходной поток с файловым дескриптором 1; может быть перенаправлен. Ещё встречается в: cat, strace
стандартный поток ошибок standard error
Поток диагностики с файловым дескриптором 2, отдельный от стандартного вывода.
файловый дескриптор file descriptor
Неотрицательное целое число, которым процесс ссылается на открытый файл, канал или сокет. По соглашению 0, 1 и 2 — стандартные потоки; открытые дескрипторы процесса перечислены в /proc/<PID>/fd. Ещё встречается в: flock, lsof, strace, ulimit и лимиты процесса: открытые файлы, процессы, core
конвейер (pipeline)
Цепочка команд через |: стандартный вывод каждой команды подаётся на стандартный ввод следующей, команды работают одновременно. Код завершения конвейера — код последней команды, если не включён pipefail. Ещё встречается в: Коды завершения: $?, && и ||, sort, wc, head и ещё 16
/dev/null
Особый файл-устройство: принимает любой вывод и ничего не хранит, а чтение из него сразу даёт конец файла. 2> /dev/null выбрасывает сообщения об ошибках. Ещё встречается в: /proc: процессы и ядро в виде файлов, AppArmor, find, HTTP и ещё 4
фильтр filter
Команда, которая читает файл или стандартный ввод, обрабатывает текст и печатает результат в стандартный вывод: grep, head, sort, uniq, wc. Фильтры соединяют в конвейер. Ещё встречается в: fail2ban, jq, conntrack (отслеживание соединений), ss и ещё 29

См. также

  • bash — оболочка, которая выполняет перенаправления.
  • tee — разветвить поток: на экран и в файл, в том числе с sudo.
  • cat — склеить файлы и записать короткий текст через <<EOF.
  • grep — главный фильтр в конвейерах.
  • sort, uniq, cut, wc — фильтры, из которых собирают конвейер.
  • text-tools — tr, paste, column, comm и другие звенья конвейера.
  • xargs — превратить вывод в аргументы следующей команды.
  • bash-scripting — set -o pipefail и коды возврата в скриптах.
Загрузка…