Как остановить перенаправление в bash

8

Я использую :

exec >script.log 2>&1

в моем скрипте перенаправить весь вывод в файл. В конце сценария я хотел бы вывести сообщение на экран. Как мне остановить перенаправление?

Willem
источник

Ответы:

12

Вы можете позвонить еще execраз, чтобы восстановить оригинальные дескрипторы. Вам нужно их где-то сохранить.

exec 3>&1 4>&2 1>script.log 2>&1
 logged portion 
exec 1>&3 2>&4
echo >&2 "Done"

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

echo "30 seconds remaining" >&3

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

{
 logged portion 
} >script.log 2>&1
echo >&2 "Done"
Жиль "ТАК - перестань быть злым"
источник
Замечание о том, чтобы >&3повторить это, делает это моим предпочтительным решением. Еще раз спасибо)!
Виллем
6

Используйте дополнительные fd 3 и 4 для stdout и stderr и просто перенаправьте 1 и 2 на них в конце вашего скрипта:

exec 3>&1 4>&2
exec >script.log 2>&1

echo "Some code"

exec >&3 2>&4
echo "Done"
порыв
источник
Это возвращает ошибку:exec 3>/dev/stdout 4>/dev/stderr -bash: /dev/stdout: Permission denied
Виллем
Эта ошибка может возникать, когда вы пытаетесь запустить свой скрипт у другого пользователя. Вы используете свой сценарий через sudo?
Раш
Да, вот и все: я сделал su для другой учетной записи и запустил код. Скрипт, который я пишу, будет запускаться через sudo, поэтому я столкнусь с той же проблемой. Есть ли альтернатива?
Виллем
Я полагаю, что есть какое-то элегантное решение, к сожалению, я знаю единственный вариант, который может быть абсолютно неприемлемым с точки зрения безопасности: добавьте вашего целевого пользователя в первоначальную первичную группу пользователей и добавьте разрешения на запись в группу для / proc / self / fd / 1. до запуска скрипта. (или даже более уязвимым - просто сделайте временное разрешение на запись для всех и удалите его сразу после завершения сценария без изменения группы).
Раш
1
@Willem Это легко исправить, используя файловые дескрипторы вместо того, чтобы открывать файлы, см. Мои правки.
Жиль "ТАК ... перестать быть злым"
1

Сначала вы должны проверить, есть ли у вас tty вообще.

if tty -s; then
    echo "Hello, World" > $(tty)
fi
Дэвид Баггерман
источник
1
Обратите внимание, что этот способ не может передавать выходные данные во внешнюю программу.
Раш
Нет необходимости использовать внешнюю ttyутилиту. Вы можете перенаправить на специальное устройство /dev/tty.
Приостановлено до дальнейшего уведомления.