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


8

Я использую :

exec >script.log 2>&1

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

Ответы:


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.
Приостановлено до дальнейшего уведомления.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.