Восстановление вывода на терминал после выдачи «exec &> filename»


15

Я пытаюсь выполнить следующее:

exec &>filename

После этого я не могу видеть ничего, включая то, что я напечатал, хорошо.

Я отчаянно стараюсь, exec 1>&1и exec 2>&2, но ничего не происходит.

Теперь, не убивая оболочку, как мне вернуть выходные данные, перенаправленные на стандартный вывод, и ошибки, перенаправленные на стандартный поток ошибок соответственно? Являются ли файловые дескрипторы единственным способом ссылки на стандартные [in | out] put и stderr?


1
Хм ... почему вы перенаправляете stderr / stdout вашей интерактивной оболочки? Эта execконструкция обычно используется в сценариях, которые запускаются в подоболочке, для перенаправления их вывода, например, в файл. Я не вижу смысла в этом в интерактивном сеансе.
Мартин фон Виттих,

3
@MartinvonWittich Я согласен с утверждением на exec. Я согласен. Я просто ребенок, играющий вокруг :)
user917279

Ответы:


23

После запуска exec &>filenameстандартный вывод и стандартная ошибка оболочки переходят в filename. Стандартный ввод - это дескриптор файла 0 по определению, стандартный вывод - fd 1, а стандартная ошибка - fd 2.

Файловый дескриптор не перенаправлен и не перенаправлен: он всегда куда-то идет (при условии, что процесс имеет этот открытый дескриптор). Перенаправить файловый дескриптор означает изменить, куда он идет. При запуске exec &>filenamestdout и stderr ранее были подключены к терминалу и стали подключаться к filename.

Существует всегда способ обращения к текущему терминалу: /dev/tty. Когда процесс открывает этот файл, это всегда означает управляющий терминал процесса , какой бы он ни был. Так что, если вы хотите вернуть исходные stdout и stderr этой оболочки, вы можете сделать это, потому что файл, к которому они были подключены, все еще существует.

exec &>/dev/tty

1
как ответил @Joseph R. $ (tty) показывает мне / dev / pty0, но ваша команда тоже работает, какая из них более переносима во всех разновидностях Unix? спасибо тебе за более четкий ответ.
user917279

2
@ user917279 Они одинаково переносимы в смысле работы над различными версиями Unix. /dev/ttyработает в случаях, когда $(tty)это не так: /dev/ttyработает до тех пор, пока у процесса есть управляющий терминал (это лучшее, на что можно надеяться, поскольку должно быть что-то, все еще связывающее процесс с терминалом), тогда как $(tty)требует, чтобы терминал все еще был открыт на стандартном вводе.
Жиль "ТАК - перестань быть злым"

11

Ты хочешь

exec &>$(tty)

В вашем вопросе вы реплицируете в stdout и stderr исходные stdout и stderr, которые уже были перенаправлены в файл.

Как объясняет ответ Жиля, ttyвернет терминальное устройство текущего терминала. Это то место, откуда три стандартных файловых дескриптора приходят / собираются по умолчанию в оболочке входа в систему. Таким образом, вышеприведенный оператор использует ttyперенаправление stdout и stderr обратно на терминальное устройство, как это было раньше.

Если вы беспокоитесь о переносимости (согласно вашему комментарию к ответу Жиля), оба метода ( утилита tty и /dev/ttyфайл ) соответствуют стандарту POSIX.

Скопировано дословно из комментария Жиля:

There's an advantage to /dev/tty: it works even after exec <somefile, 
whereas $(tty) would complain “not a tty”

оно работает! Спасибо. echo $ (tty) дает / dev / pty0 (в cygwin), как это связано с stdin, stdout и что происходит с приведенным выше оператором? пожалуйста, дайте мне знать, если мне нужно задать это как отдельный вопрос.
user917279

@ user917279 Ответ обновлен.
Джозеф Р.

Спасибо, Джозеф. Я разместил этот вопрос, прежде чем посмотреть на ответ Джайлза. Большое спасибо. Пожалуйста, позвольте мне отметить ответ Джайлза как принятый, потому что он заставил даже глупых умов, как мой, правильно понять.
user917279

2
Есть преимущество в том, что /dev/ttyоно работает даже после того exec <somefile, как $(tty)будет жаловаться «не тент».
Жиль "ТАК - перестань быть злым"

@Gilles Спасибо за характерно поучительный комментарий :)
Джозеф Р.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.