Co robi „3> i 1 1> i 2 2> i 3” w skrypcie?

Odpowiedzi:

77

Liczby są deskryptorami plików i tylko trzy pierwsze (zaczynające się od zera) mają znormalizowane znaczenie:

0 - stdin
1 - stdout
2 - stderr

Tak więc każda z tych liczb w twoim poleceniu odnosi się do deskryptora pliku. Możesz przekierować deskryptor pliku do pliku za pomocą >lub przekierować go do innego deskryptora pliku za pomocą>&

3>&1W linii poleceń stworzy nowy deskryptor pliku i przekierować go 1co jest STDOUT. Teraz 1>&2przekieruje deskryptor pliku 1 do STDERRi 2>&3przekieruje deskryptor pliku 2 do 3, który jest STDOUT.

Więc w zasadzie przeszedłeś STDOUTi STDERRsą to następujące kroki:

  1. Utwórz nowy fd 3 i skieruj go na fd 1
  2. Przekieruj deskryptor pliku 1 na deskryptor pliku 2. Gdybyśmy nie zapisali deskryptora pliku w 3, stracilibyśmy cel.
  3. Przekieruj deskryptor pliku 2 na deskryptor pliku 3. Teraz deskryptory plików 1 i 2 są przełączane.

Teraz, jeśli program wydrukuje coś do deskryptora pliku 1, zostanie to wypisane do deskryptora pliku 2 i odwrotnie.

Ulrich Dangel
źródło
Powiedziałeś: „3> i 1 w linii poleceń utworzy nowy deskryptor pliku i przekieruje go do 1, który jest STDOUT”. Ale czy 1 nie oznacza STDIN?
sofs1,
19

Zamiana stdouti stderr.

>nameoznacza przekierowanie wyjścia do pliku name.

>&numberoznacza przekierowanie wyjścia do deskryptora pliku number.

&Potrzebne jest więc , aby powiedzieć powłoce, że masz na myśli deskryptor pliku, a nie nazwę pliku.

Deskryptor pliku to liczba odnosząca się do już otwartego pliku. Standardowe są 0dla standardowego wejścia, 1dla standardowego wyjścia lub 2dla standardowego błędu. Możesz także użyć dowolnej innej liczby, która utworzy nowy deskryptor pliku, podobnie jak podczas tworzenia nowej zmiennej za pomocą var=value.

Domyślnie zarówno deskryptor pliku, jak 1i 2przejdź do /dev/tty, więc jeśli uruchomisz somecommand 3>&1 1>&2 2>&3nową powłokę, nic to nie zmieni (z wyjątkiem teraz, gdy masz deskryptor pliku nr 3).

Ale jeśli gdzieś wcześniej w skrypcie dokonuje przekierowania za pomocą exec (np. exec 2>error.log), Lub skrypt jest uruchamiany z linii poleceń zawierającej przekierowanie (np. ./thescript 2>error.log), Wówczas zamiana stdout i stderr zrobi coś.

W twoim konkretnym przypadku polecenie, które ma zamienione stdout i stderr, to dialog. Widzę, patrząc na stronę podręcznika

Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error

więc być może osoba, która napisała skrypt, chce dialog, aby stdoutz stderrjakiegoś powodu wynik był wyświetlany.

Zobacz także Kolejność przekierowań

Mikel
źródło
1

Autor skryptów zdefiniował FD 3, takie jak:

exec 3<> File.txt

Otwórz „File.txt” i przypisz do niego fd 3. Maksymalna liczba deskryptorów plików: 255

read -n 4 <&3

Czytaj tylko 4 znaki.

echo -n . >&3

Wpisz tam przecinek dziesiętny.

exec 3>&-

Zamknij fd 3.

cat File.txt

==> 1234,67890

Jonathan Jackson
źródło