Ho difficoltà a capire come si usano i descrittori di file negli script di shell.
Conosco le basi come
exec 5 > /tmp/foo
Quindi fd 5 è allegato a foo per la scrittura.
exec 6 < /tmp/bar
… per la lettura.
exec 5>&-
… chiudi fd.
Ora cosa fa questo?
#!/bin/bash
exec 5 > /tmp/foo
exec 6 < /tmp/bar
cat <&6 | while read a
do
echo $a >&5
done
A quanto ho capito &5
chiude l'FD, quindi in che modo l'output viene ancora reindirizzato correttamente dopo ogni chiamata?
Questa è una copia della pasta da :Qui
Afferma di usarlo su un semplice echo $a > file
renderebbe molto più veloce, tuttavia non riesco a capire. Apprezzerei qualsiasi link a tutorial decente. I poteri di Google sembrano deludermi.
Risposta accettata:
Innanzitutto, nota che la sintassi per la chiusura è 5>&-
o 6<&-
, a seconda che il descrittore di file venga letto per la scrittura o per la lettura. Sembra che ci sia un errore di battitura o di formattazione in quel post del blog.
Ecco lo script commentato.
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 #
Non c'è chiusura qui. Poiché in questo semplice esempio tutti gli input e gli output vanno nella stessa posizione, non è necessario l'uso di descrittori di file aggiuntivi. Potresti scrivere
cat </tmp/bar |
while read a; do
echo $a
done >/tmp/foo
L'uso di descrittori di file espliciti diventa utile quando si desidera scrivere a turno su più file. Si consideri, ad esempio, uno script che invia i dati a un file di output dei dati e registra i dati in un file di registro ed eventualmente anche i messaggi di errore. Ciò significa tre canali di output:uno per i dati, uno per i log e uno per gli errori. Poiché ci sono solo due descrittori standard per l'output, è necessario un terzo. Puoi chiamare exec
per aprire i file di output:
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
L'osservazione sull'efficienza arriva quando hai un reindirizzamento in un ciclo, come questo (supponendo che il file sia vuoto per cominciare):
while …; do echo $a >>/tmp/bar; done
Ad ogni iterazione, il programma apre /tmp/bar
, cerca la fine del file, aggiunge alcuni dati e chiude il file. È più efficiente aprire il file una volta per tutte:
while …; do echo $a; done >/tmp/bar
Quando si verificano più reindirizzamenti in momenti diversi, chiamando exec
per eseguire reindirizzamenti anziché racchiudere un blocco in un reindirizzamento diventa utile.
exec >/tmp/bar
while …; do echo $a; done
Troverai molti altri esempi di reindirizzamento sfogliando il io-redirection
tag su questo sito.