В bash вызов foo
будет отображать любой вывод этой команды на стандартный вывод.
Вызов foo > output
перенаправит любой вывод этой команды в указанный файл (в данном случае «output»).
Есть ли способ перенаправить вывод в файл и показать его на стандартный вывод?
foo > output
данных будет выводится на стандартный вывод и стандартный вывод является файл с именемoutput
. То есть запись в файл - это запись в стандартный вывод. Вы спрашиваете, возможно ли написать как на стандартный вывод, так и на терминал.Ответы:
Команда, которую вы хотите, называется
tee
:Например, если вы заботитесь только о stdout:
Если вы хотите включить stderr, выполните:
2>&1
перенаправляет канал 2 (стандартный вывод / стандартная ошибка) в канал 1 (стандартный вывод / стандартный вывод), так что оба записываются как стандартный вывод. Он также направляется в данный выходной файл какtee
команда.Кроме того, если вы хотите добавить в файл журнала, используйте
tee -a
как:источник
-a
аргументtee
для добавления содержимогоoutput.file
вместо того, чтобы перезаписывать его:ls -lR / | tee -a output.file
$?
впоследствии, он вернет код состоянияtee
, что, вероятно, не то, что вы хотите. Вместо этого вы можете использовать${PIPESTATUS[0]}
.2>&1
выводит потоки stderr и stdouttee outfile
берет полученный поток и записывает его на экран и в файл «outfile».Это, вероятно, то, что ищет большинство людей. Скорее всего, какая-то программа или скрипт долго работают и выдают много результата. Пользователь хочет периодически проверять его на предмет прогресса, но также хочет, чтобы вывод был записан в файл.
Проблема (особенно при смешивании потоков stdout и stderr) состоит в том, что существует зависимость от потоков, сбрасываемых программой. Если, например, все записи на стандартный вывод будут не покраснел, но все записи в STDERR являются покраснел, то они будут в конечном итоге из хронологической последовательности в выходном файле и на экране.
Также плохо, если программа выдает только 1 или 2 строки каждые несколько минут, чтобы сообщить о прогрессе. В таком случае, если вывод не был сброшен программой, пользователь даже часами не будет видеть вывод на экране, потому что ни один из них не будет проталкиваться через канал в течение нескольких часов.
Обновление: программа
unbuffer
, входящая вexpect
пакет, решит проблему буферизации. Это заставит stdout и stderr немедленно записать на экран и в файл и синхронизировать их при объединении и перенаправлении наtee
. Например:источник
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
имеет встроенную опцию,-u
которая снимает буфер с вывода.Другой способ, который работает для меня, это
как показано в руководстве по GNU Bash
Пример:
Для получения дополнительной информации см. Перенаправление
источник
$?
впоследствии, он вернет код состоянияtee
, что, вероятно, не то, что вы хотите. Вместо этого вы можете использовать${PIPESTATUS[0]}
.В первую очередь вы можете использовать решение Zoredache , но если вы не хотите перезаписывать выходной файл, вы должны написать команду с параметром -a следующим образом:
источник
Что-то добавить ...
Unbuffer пакета имеет проблемы с поддержкой некоторых пакетов в выпусках fedora и redhat unix.
Откладывая в сторону неприятности
Следующее сработало для меня
источник
Использование
tail -f output
должно работать.источник
Бонусный ответ, так как этот вариант использования привел меня сюда:
В случае, если вам нужно сделать это как какой-то другой пользователь
Обратите внимание, что эхо произойдет, когда вы и запись в файл произойдут как «some_user», что НЕ будет работать, если вы запустите эхо как «some_user» и перенаправите вывод с помощью >> «some_file», потому что произойдет перенаправление файла как и ты.
Подсказка: tee также поддерживает добавление с флагом -a, если вам нужно заменить строку в файле другим пользователем, вы можете выполнить sed в качестве нужного пользователя.
источник
< command > |& tee filename
# это создаст файл «имя файла» с статусом команды в качестве контента. Если файл уже существует, он удалит существующий контент и запишет статус команды.< command > | tee >> filename
# это добавит статус к файлу, но не выведет статус команды на standard_output (screen).Я хочу напечатать что-нибудь с помощью «эхо» на экране и добавить эти данные в файл
источник
Вы можете сделать это для всего скрипта, используя что-то подобное в начале скрипта:
Это редирект как потоки вывода выводит в файл с именем ,
mylogfile
и пусть все идет на стандартный вывод одновременно .Используются некоторые глупые трюки:
exec
без команды для настройки перенаправлений,tee
для дублирования выходов,NUL
символ, указанный в$'string'
специальной нотации bash), чтобы указать, что сценарий перезапускается (никакие эквивалентные параметры не могут использоваться в вашей исходной работе),pipefail
параметра.Некрасиво, но полезно для меня в определенных ситуациях.
источник
тройник идеально подходит для этого, но это также сделает работу
источник
;
, вывод будет сильно задерживаться во время медленной команды.