Можно ли перенаправить все выходные данные сценария оболочки Bourne куда-нибудь, но с помощью команд оболочки внутри самого сценария?
Перенаправить вывод одной команды легко, но я хочу что-то вроде этого:
#!/bin/sh
if [ ! -t 0 ]; then
# redirect all of my output to a file here
fi
# rest of script...
Значение: если скрипт запускается не в интерактивном режиме (например, cron), сохраните все данные в файле. Если он запускается в интерактивном режиме из оболочки, пусть вывод идет в стандартный вывод.
Я хочу сделать это для скрипта, обычно запускаемого периодической утилитой FreeBSD. Это часть ежедневной работы, которую я, как правило, не хочу видеть каждый день в электронной почте, поэтому мне ее не отправляют. Однако, если что-то внутри этого конкретного сценария не работает, это важно для меня, и я хотел бы иметь возможность собирать и отправлять по электронной почте результаты этой части ежедневных заданий.
Обновление: ответ Джошуа точный, но я также хотел сохранить и восстановить stdout и stderr по всему сценарию, что делается так:
# save stdout and stderr to file descriptors 3 and 4, then redirect them to "foo"
exec 3>&1 4>&2 >foo 2>&1
# ...
# restore stdout and stderr
exec 1>&3 2>&4
exec 1>&3 2>&4 3>&- 4>&-
Ответы:
Решение вопроса как обновлено.
Скобки '{...}' обеспечивают единицу перенаправления ввода / вывода. Скобки должны появляться там, где может появиться команда - упрощенно, в начале строки или после точки с запятой. ( Да, это может быть уточнено; если вы хотите поспорить, дайте мне знать. )
Вы правы в том, что вы можете сохранить исходные stdout и stderr с указанными вами перенаправлениями, но людям, которым необходимо поддерживать скрипт позже, обычно проще понять, что происходит, если вы расширяете область действия перенаправленного кода, как показано выше.
Соответствующие разделы руководства Bash - это команды группировки и перенаправление ввода / вывода . Соответствующие разделы спецификации оболочки POSIX - это составные команды и перенаправление ввода / вывода . Bash имеет некоторые дополнительные нотации, но в остальном похож на спецификацию оболочки POSIX.
источник
>>
. У некоторых людей есть привычка>
. Аппендинг всегда безопаснее и рекомендуется, чем овергинг. Кто-то написал приложение, которое использует стандартную команду копирования для экспорта некоторых данных в тот же пункт назначения.Обычно мы помещаем один из них в верхнюю часть скрипта или около него. Скрипты, которые анализируют свои командные строки, будут выполнять перенаправление после анализа.
Отправить стандартный вывод в файл
с stderr
добавить как stdout, так и stderr в файл
Как отметил Джонатан Леффлер в своем комментарии :
exec
имеет две отдельные работы. Первый - заменить текущую исполняемую оболочку (скрипт) новой программой. Другой - изменение перенаправлений ввода / вывода в текущей оболочке. Это отличает отсутствие аргументовexec
.источник
exec
имеет две отдельные работы. Один из них - заменить текущий скрипт другой командой, используя тот же процесс - вы указываете другую команду в качестве аргументаexec
(и вы можете настроить перенаправление ввода / вывода, как вы это делаете). Другая задача - изменение перенаправлений ввода / вывода в текущем сценарии оболочки без замены. Эта запись отличается отсутствием команды в качестве аргументаexec
. Обозначение в этом ответе относится к варианту «только ввод-вывод» - он только изменяет перенаправление и не заменяет запущенный скрипт. (Командаset
аналогично многоцелевой.)exec > >(tee -a "logs/logdata.log") 2>&1
печатает логи на экране, а также записывает их в файлВы можете сделать весь скрипт такой функцией:
тогда в конце скрипта есть это:
В качестве альтернативы, вы можете записывать все в файл журнала при каждом запуске и по-прежнему выводить его на стандартный вывод, просто выполнив:
источник
Для сохранения оригинальных stdout и stderr вы можете использовать:
Например, следующий код выведет «walla1» и «walla2» в файл журнала (
a.txt
), «walla3» в stdout, «walla4» в stderr.источник
exec 5>&1
иexec 6>&2
, используя нотацию перенаправления вывода, а не нотацию перенаправления ввода для выходов. Вам это сходит с рук, потому что когда скрипт запускается из терминала, стандартный ввод также доступен для записи, и как стандартный вывод, так и стандартная ошибка читаются благодаря исторической причуде (или это «порок»?): Терминал открыт для чтение и запись, и одно и то же описание открытого файла используется для всех трех стандартных файловых дескрипторов ввода / вывода.источник