Перенаправление вывода и конвейеры
Оболочка направляет ввод и вывод команды в файл или в другую команду: >, >>, 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 | ошибки и предупреждения: тоже экран |
Перенаправление — указание оболочке подключить поток к файлу или к другой команде. Его выполняет оболочка до запуска команды, сама команда о нём не знает. Поэтому ошибки видны на экране, даже когда вывод ушёл в файл:
2>&1 значит «поток 2 туда же, куда сейчас идёт поток 1». Конвейер | соединяет
stdout одной команды со stdin следующей; все звенья работают одновременно.
Рецепты
7Порядок 2>&1 имеет значение
Оболочка читает перенаправления слева направо. Во второй строке 2>&1 копирует
то, куда stdout указывал в тот момент, — экран.
Обработать вывод цепочкой команд
Записать в файл, которому нужен root
sudo cmd > /etc/файл не сработает: перенаправление делает твоя оболочка без
прав root. tee запускается через sudo и пишет сам.
Многострочный ввод прямо в команду
Очистить журнал, не удаляя файл
Если процесс держит журнал открытым, rm не вернёт место, а обнуление вернёт.
Узнать, какое звено конвейера упало
Неполадки
6Permission 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и коды возврата в скриптах.
Есть неточность? Сообщить об ошибке в статье