Po pierwsze, zwróć uwagę, że składnia zamykania jest 5>&-
lub 6<&-
, w zależności od tego, czy deskryptor pliku jest odczytywany do zapisu, czy do odczytu. Wydaje się, że w tym wpisie na blogu występuje literówka lub usterka formatowania.
Oto skomentowany skrypt.
exec 5>/tmp/foo # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar # open /tmp/bar for reading, on fd 6
cat <&6 | # call cat, with its standard input connected to
# what is currently fd 6, i.e., /tmp/bar
while read a; do #
echo $a >&5 # write to fd 5, i.e., /tmp/foo
done #
Tu nie ma zamknięcia. Ponieważ w tym prostym przykładzie wszystkie dane wejściowe i wyjściowe idą w to samo miejsce, użycie dodatkowych deskryptorów plików nie jest konieczne. Mógłbyś pisać
cat </tmp/bar |
while read a; do
echo $a
done >/tmp/foo
Używanie jawnych deskryptorów plików staje się przydatne, gdy chcesz pisać po kolei do wielu plików. Rozważmy na przykład skrypt, który wysyła dane do pliku wyjściowego danych i rejestruje dane do pliku dziennika, a także ewentualne komunikaty o błędach. Oznacza to trzy kanały wyjściowe: jeden dla danych, jeden dla dzienników i jeden dla błędów. Ponieważ istnieją tylko dwa standardowe deskryptory dla danych wyjściowych, potrzebny jest trzeci. Możesz zadzwonić, exec
aby otworzyć pliki wyjściowe:
exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&- # close the data output file
echo "output file closed" >&3
Uwaga o wydajności pojawia się, gdy masz przekierowanie w pętli, takie jak to (zakładając, że plik jest pusty na początek):
while …; do echo $a >>/tmp/bar; done
Przy każdej iteracji program otwiera się /tmp/bar
, szuka końca pliku, dołącza pewne dane i zamyka plik. Bardziej efektywne jest otwarcie pliku raz na zawsze:
while …; do echo $a; done >/tmp/bar
Gdy występuje wiele przekierowań w różnych momentach, exec
przydatne staje się wywołanie przekierowania zamiast zawijania bloku w przekierowaniu.
exec >/tmp/bar
while …; do echo $a; done
Znajdziesz kilka innych przykładów przekierowania, przeglądając io-redirection
tag na tej stronie .