Jak zrozumieć kolejność przekierowania wyjścia? [duplikować]

10

Próbuję nauczyć się przekazywać standardowe i standardowe błędy w różnych obszarach.

Załóżmy, że mam folder z samym here.txt .

Więc jeśli to zrobię

ls here.txt not-here.txt  1>out  2>&1

Ponieważ here.txt jest obecny, będę miał jakieś dane wyjściowe do pliku out , ale ponieważ not-here.txt nie jest obecny, błąd zostanie wysłany przez standardowy błąd, który przekierowuję na standardowe wyjście z 2>&1 .

Dlaczego jednak to nie działa:

ls here.txt not-here.txt 2>&1 1>out

Wydaje się, że działa tylko wtedy, gdy wykonuję przekierowanie po wydaniu standardowej instrukcji? Dlaczego?

    
zadawane Aruka J 24.09.2017, 17:33
źródło

3 odpowiedzi

5

Kolejność przekierowań jest znacząca . Na przykład polecenie

ls > dirlist 2>&1

kieruje zarówno standardowe wyjście, jak i standardowy błąd do pliku dirlisty, podczas gdy polecenie

ls 2>&1 > dirlist

kieruje tylko standardowe wyjście do pliku dirlisty, ponieważ standardowy błąd został zduplikowany ze standardowego wyjścia (zazwyczaj wciąż wskazuje okno terminala), zanim standardowe wyjście zostanie przekierowane do katalogu.

Początkowo może to wydawać się sprzeczne z intuicją, ale po przemyśleniu tego możemy to zrozumieć.

Wyjaśnienie to znajduje się w man bash , w rozdziale o przekierowaniu,

  

REDIRECTION

     

Przed wykonaniem polecenia jego wejście i wyjście może zostać przekierowane za pomocą specjalnej notacji interpretowanej przez powłokę. Przekierowanie pozwala na kopiowanie, otwieranie, zamykanie plików uchwytów plików w celu odniesienia się do różnych plików oraz na zmianę plików, z których odczytuje i zapisuje polecenia. Przekierowanie może również służyć do modyfikowania uchwytów plików w bieżącym środowisku wykonania powłoki. Następujące operatory przekierowania mogą poprzedzać lub pojawiać się w dowolnym miejscu prostego polecenia lub mogą wykonywać polecenia. Przekierowania są przetwarzane w kolejności, w jakiej się pojawiają, od lewej do prawej.

     

Każde przekierowanie, które może być poprzedzone numerem deskryptora pliku, może być poprzedzone słowem w postaci {varname} . W tym przypadku dla każdego operatora przekierowania z wyjątkiem >&- i <&- , powłoka przydzieli deskryptor pliku większy lub równy 10 i przypisze go do varname . Jeśli >&- lub <&- jest poprzedzone {varname} , wartość varname określa deskryptor pliku do zamknięcia.

     

W poniższych opisach, jeśli numer deskryptora pliku zostanie pominięty, a pierwszy znak operatora przekierowania to < , przekierowanie odnosi się do standardowego wejścia (deskryptor pliku 0). Jeśli pierwszym znakiem operatora przekierowania jest > , przekierowanie odnosi się do standardowego wyjścia (deskryptor pliku 1).

     

Słowo następujące po operatorze przekierowania w poniższych opisach, o ile nie zaznaczono inaczej, podlega rozszerzeniu nawiasów, rozszerzeniu tyld, rozszerzeniu parametrów i zmiennych, podstawianiu poleceń, rozszerzeniu arytmetycznym, usunięciu cudzysłowu, rozwinięciu nazwy ścieżki i dzieleniu słów. Jeśli rozszerza się na więcej niż jedno słowo, bash zgłasza błąd.

     

Zwróć uwagę, że kolejność przekierowań jest znaczna. Na przykład polecenie

ls > dirlist 2>&1
     

kieruje zarówno standardowe wyjście, jak i standardowy błąd do pliku dirlist , podczas gdy polecenie

ls 2>&1 > dirlist
     

kieruje tylko standardowe wyjście do pliku dirlist , ponieważ standardowy błąd został zduplikowany ze standardowego wyjścia zanim standardowe wyjście zostało przekierowane do dirlist .

Edycja: poniższe linie poleceń mogą wyjaśniać, co się dzieje

Przygotuj

sudodus@xenial32:~$ touch qwerty;rm asdf
rm: cannot remove 'asdf': No such file or directory

Uruchom polecenie list dla jednego istniejącego pliku i jednego nieistniejącego pliku

sudodus@xenial32:~$ ls qwerty asdf
ls: cannot access 'asdf': No such file or directory
qwerty

Przekieruj wyjście błędów przed przekierowaniem standardowego wyjścia. Tylko standardowe wyjście jest przekierowywane do pliku wyjściowego.

sudodus@xenial32:~$ ls qwerty asdf 2>&1 > output-file ;echo '---';cat output-file 
ls: cannot access 'asdf': No such file or directory
---
qwerty

Przekieruj wyjście błędów po przekierowaniu standardowego wyjścia. Zarówno wyjście błędów, jak i standardowe wyjście są przekierowywane do pliku wyjściowego.

sudodus@xenial32:~$ ls qwerty asdf > output-file 2>&1 ;echo '---';cat output-file
---
ls: cannot access 'asdf': No such file or directory
qwerty

Token &> może być użyty do przekierowania zarówno błędu standardowego, jak i standardowego. Może być używany w bash , ale może nie być dostępny w innych powłokach.

sudodus@xenial32:~$ ls qwerty asdf &> output-file ;echo '---';cat output-file
---
ls: cannot access 'asdf': No such file or directory
qwerty
sudodus@xenial32:~$ 
    
odpowiedział sudodus 24.09.2017, 17:57
źródło
3
  • 2>x oznacza, że ​​nazwa pliku x otrzyma dane zapisane do deskryptora 2 (znany również jako stderr, błąd standardowy)
  • ... ale gdy x jest określony jako &1 , nie oznacza to, że "zawsze podążaj za 1 "; oznacza to "skopiować bieżące właściwości 1 (a następnie pozostawić je w spokoju)" .
  • Przekierowania są stosowane w tej samej kolejności, co w wierszu poleceń, ale przed faktycznym wykonaniem.

Z tego powodu 2>&1 1>whatever wyprowadza stderr na terminal.

To jest powód, dla którego find / -name mylostfile.txt 3>&1 1>&2 2>&3 | grep -v 'Permission denied' wymienia stderr i stderr, dzięki czemu możesz odfiltrować niektóre wspólne linie stderr, ale nadal widzisz stdout. (Deskryptor 3 jest tutaj nieużywany przez programy).

    
odpowiedział kubanczyk 24.09.2017, 22:59
źródło
2

Powłoka napotyka i ustawia w kolejności, w jakiej widzi rzecz. W pierwszym przypadku:

ls here.txt not-here.txt  1>out  2>&1

Dane wyjściowe są przekierowywane, a następnie błąd standardowy wysyłany jest w to samo miejsce.

W drugim przypadku

ls here.txt not-here.txt 2>&1 1>out

Wyjście standardowe jest nadal ustawione na terminal, więc do terminalu wysyłany jest standardowy błąd. Powłoka już ustawiła błąd standardowy.

    
odpowiedział jpezz 24.09.2017, 18:01
źródło

Przeczytaj inne pytania na temat tagów