Przywracanie danych wyjściowych do terminala po wydaniu „exec &> filename”


15

Próbuję wykonać następujące czynności:

exec &>filename

Po tym nie widzę nic, w tym tego, co napisałem, w porządku.

I gorączkowo próbować, exec 1>&1i exec 2>&2, ale nic się nie dzieje.

Teraz, bez zabijania powłoki, w jaki sposób mogę odzyskać dane wyjściowe przekierowane odpowiednio na stdout i błąd przekierowany odpowiednio do stderr? Czy deskryptory plików to jedyny sposób odwoływania się do standardowych [wejściowych | wyjściowych] put i stderr?


1
Hmm ... dlaczego więc przekierowujesz stderr / stdout swojej interaktywnej powłoki? Ta execkonstrukcja jest zwykle używana w skryptach uruchamianych w podpowłoce, aby przekierowywać dane wyjściowe, np. Do pliku. Nie widzę zastosowania w sesji interaktywnej.
— Martin von Wittich,

3
@MartinvonWittich Zgadzam się z oświadczeniem dotyczącym exec. Zgadzam się. Jestem tylko dzieckiem
— bawiącym się

Odpowiedzi:


23

Po uruchomieniu exec &>filenamestandardowe wyjście i standardowy błąd powłoki trafiają do filename. Standardowe wejście to z definicji deskryptor pliku 0, a standardowe wyjście to fd 1, a standardowy błąd to fd 2.

Deskryptor pliku nie jest ani przekierowany, ani nie przekierowany: zawsze gdzieś idzie (zakładając, że proces ma otwarty ten deskryptor). Przekierowanie deskryptora pliku oznacza zmianę kierunku. Kiedy exec &>filenamebiegałeś, stdout i stderr były wcześniej podłączone do terminala i łączyły się z filename.

Nie zawsze jest sposób, aby zapoznać się z bieżącym terminalu: /dev/tty. Gdy proces otwiera ten plik, zawsze oznacza terminal kontrolny procesu , w zależności od tego, co to jest. Więc jeśli chcesz odzyskać oryginalny stdout i stderr tej powłoki, możesz to zrobić, ponieważ plik, z którym byli połączeni, wciąż istnieje.

exec &>/dev/tty

1
jak @Joseph R. odpowiedział $ (tty) pokazuje mi / dev / pty0, ale twoje polecenie też działa, który jest bardziej przenośny w różnych wersjach Uniksa? dziękuję za bardziej jednoznaczną odpowiedź.
— user917279,

2
@ user917279 Są równie przenośne w sensie pracy nad różnymi smakami uniksowymi. /dev/ttydziała w przypadkach, w których $(tty)nie /dev/ttydziała : działa, dopóki proces ma terminal sterujący (co jest najlepszym, na co możesz mieć nadzieję, ponieważ musi być jeszcze coś łączącego proces z terminalem), podczas gdy $(tty)wymaga, aby terminal był nadal otwarty na standardowym wejściu.
— Gilles „SO- przestań być zły”

Dlaczego exec &>/dev/ttynie exec >/dev/tty?
— Anthony Rutledge

@AnthonyRutledge Ponieważ pytanie dotyczy tego, co robić później exec &>filename, a nie co robić później exec >filename.
— Gilles „SO- przestań być zły”

11

Chcesz

exec &>$(tty)

To, co robisz w swoim pytaniu, to replikacja w stdout i stderr oryginalnego stdout i stderr, które zostały już przekierowane do pliku.

Jak wyjaśnia odpowiedź Gillesa, ttyzwróci urządzenie końcowe bieżącego terminala. To tutaj domyślnie przychodzą / przechodzą trzy standardowe deskryptory plików w powłoce logowania. Tak więc powyższe oświadczenie wykorzystuje ttyprzekierowanie stdout i stderr z powrotem do urządzenia końcowego, tak jak poprzednio.

Jeśli obawiasz się o przenośność (zgodnie z komentarzem do odpowiedzi Gillesa), obie metody ( narzędzie tty i /dev/ttyplik ) są w standardzie POSIX.

Skopiowano dosłownie komentarz Gillesa:

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

to działa! Dziękuję Ci. echo $ (tty) daje / dev / pty0 (w cygwin), w jaki sposób jest to powiązane ze stdin, stdout i co dzieje się z powyższą instrukcją? daj mi znać, jeśli będę musiał zadać to osobne pytanie.
— user917279,

@ user917279 Odpowiedź zaktualizowana.
— Joseph R.

Dziękuję Joseph. Zadałem to pytanie, zanim spojrzałem na odpowiedź Gilesa. Dziękuję Ci bardzo. Proszę pozwolić, żebym oznaczył odpowiedź Giles jako zaakceptowaną, ponieważ dzięki temu nawet głupie umysły, takie jak mój, zrozumiały właściwie.
— user917279,

2
Ma to tę zaletę, że /dev/tty: działa nawet później exec <somefile, podczas gdy $(tty)narzeka „nie tty”.
— Gilles „SO- przestań być zły”

@Gilles Dziękuję za charakterystycznie pouczający komentarz :)
— Joseph R.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.