Как перенаправить вывод в файл и стандартный вывод

529

В bash вызов foo будет отображать любой вывод из этой команды на stdout.

Вызов foo > output будет перенаправлять любой вывод из этой команды в указанный файл (в этом случае "вывод" ).

Есть ли способ перенаправить вывод в файл и показать его на stdout?

  • 2
    Если кто-то только что оказался здесь в поиске записи ошибок в файл, взгляните на - unix.stackexchange.com/questions/132511/…
Теги:
io
file-io
stdout

9 ответов

716
Лучший ответ

Требуемая команда называется tee:

foo | tee output.file

Например, если вы только заботитесь о stdout:

ls -a | tee output.file

Если вы хотите включить stderr, выполните:

program [arguments...] 2>&1 | tee outfile

2>&1 перенаправляет канал 2 (stderr/стандартная ошибка) в канал 1 (стандартный вывод/стандартный вывод), так что оба они записываются как stdout. Он также направляется к данному выходному файлу с командой tee.

Кроме того, если вы хотите добавить в файл журнала, используйте tee -a как:

program [arguments...] 2>&1 | tee -a outfile
  • 154
    Если OP хочет, чтобы «весь вывод» был перенаправлен, вам также нужно взять stderr: «ls -lR / 2> & 1 | tee output.file»
  • 9
    Этот ответ неправильный, а тот, что ниже, - правильный, не знаю, о чем идет речь.
Показать ещё 12 комментариев
391
$ program [arguments...] 2>&1 | tee outfile

2>&1 сбрасывает потоки stderr и stdout. tee outfile берет поток, который он получает, и записывает его на экран и в файл "outfile".

Это, вероятно, то, что большинство людей ищет. Вероятная ситуация - это какая-то программа, или script долго работает и производит много выходных данных. Пользователь хочет периодически проверять его на наличие прогресса, но также хочет, чтобы результат был записан в файл.

Проблема (особенно при смешивании потоков stdout и stderr) заключается в том, что существует зависимость от потоков, которые сбрасываются программой. Если, например, все записи в stdout не сбрасываются, но все записи в stderr очищаются, то они будут в конечном итоге отставать от хронологического порядка в выходном файле и на экране.

Это также плохо, если программа выводит только 1 или 2 строки каждые несколько минут, чтобы сообщить о прогрессе. В таком случае, если выход не был сброшен программой, пользователь не будет даже видеть какой-либо вывод на экране в течение нескольких часов, потому что ни один из них не будет проталкиваться через трубу в течение нескольких часов.

Обновление. Программа unbuffer, входящая в пакет expect, решит проблему буферизации. Это заставит stdout и stderr немедленно записывать на экран и файл и синхронизировать их при объединении и перенаправлении на tee. Например:.

$ unbuffer program [arguments...] 2>&1 | tee outfile
  • 0
    Нашел решение: ссылка
  • 5
    Кто-нибудь знает о «небуфере» для OSX?
Показать ещё 5 комментариев
74

Другой способ, который работает для меня, -

<command> |& tee  <outputFile>

как показано в gnu bash manual

Пример:

ls |& tee files.txt

Если '| &, command1s стандартная ошибка, в дополнение к ее стандартным выводам, подключается к стандартным входам command2s через трубу; это сокращение для 2 > & 1 |. Это неявное перенаправление стандартной ошибки на стандартный вывод выполняется после любых переназначений, указанных в команде.

Для получения дополнительной информации см. redirection

  • 6
    Если вы используете $? после этого он вернет код состояния tee , что, вероятно, не то, что вы хотите. Вместо этого вы можете использовать ${PIPESTATUS[0]} .
  • 0
    Этот метод отбрасывает цветной вывод на консоль, есть идеи?
Показать ещё 1 комментарий
43

tee - ваш друг.

whatever | tee logfile.txt
14

В основном вы можете использовать Zoredache решение, но если вы не хотите перезаписывать выходной файл, вы должны написать tee с параметром -a следующим образом:

ls -lR / | tee -a output.file
8

Что-то добавить...

В пакете unbuffer есть проблемы с поддержкой некоторых пакетов в версиях fedora и redhat unix.

Отказ от проблем

После работы для меня

bash myscript.sh 2>&1 | tee output.log

Спасибо ScDF и matthew ваши входы сэкономили мне много времени..

7

используя tail -f output, должен работать.

3

Бонусный ответ, так как этот прецедент привел меня сюда:

В случае, если вам нужно сделать это как другой пользователь

echo "some output" | sudo -u some_user tee /some/path/some_file

Обратите внимание, что эхо произойдет, когда вы и запись файла произойдет как "some_user", что будет работать NOT, если вы должны запустить echo как "some_user" и перенаправить вывод с помощью → "some_file", потому что перенаправление файлов произойдет как вы.

Подсказка: tee также поддерживает добавление с флагом -a, если вам нужно заменить строку в файле в качестве другого пользователя, который вы могли бы выполнить sed в качестве желаемого пользователя.

-9

tee идеально подходит для этого, но это также сделает работу

ls -lr / > output | cat output
  • 9
    Это ошибка, если вывод еще не существует и он не делает то, что вы хотите, если он делает, в целом это бессмысленно. Возможно, вы имели в виду ";" вместо "|" ?
  • 5
    Даже если вы использовали ; , вывод будет сильно задерживаться во время медленной команды.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню