2013-03-25 14 views
14

Sono un principiante di Bash ma sto cercando di imparare questo strumento per avere un lavoro nei computer uno di questi giorni.Bash: descrittori di file

Sto cercando di insegnare a me stesso i descrittori di file ora. Permettetemi di condividere alcuni dei miei esperimenti:


#!/bin/bash 

# Some dummy multi-line content 
read -d '' colours <<- 'EOF' 
     red 
     green 
     blue 
EOF 

# File descriptor 3 produces colours 
exec 3< <(echo "$colours") 

# File descriptor 4 filters colours 
exec 4> >(grep --color=never green) 

# File descriptor 5 is an unlimited supply of violet 
exec 5< <(yes violet) 

echo Reading colours from file descriptor 3... 
cat <&3 
echo ... done. 

echo Reading colours from file descriptor 3 again... 
cat <&3 
echo ... done. 

echo Filtering colours through file descriptor 4... 
echo "$colours" >&4 
echo ... done. # Race condition? 

echo Dipping into some violet... 
head <&5 
echo ... done. 

echo Dipping into some more violet... 
head <&5 
echo ... done. 

qualche primavera domande in mente come la vedo l'uscita proveniente da quanto sopra:

  1. fd3 sembra avere "impoverito" dopo "consumo", viene automaticamente chiuso anche dopo il primo utilizzo?
  2. come è diverso fd3 da una named pipe? (qualcosa che ho già visto)
  3. quando esattamente si avvia il comando yes? su dichiarazione FD? dopo?
  4. yes stop (CTRL-Z o altro) e riavviare quando è necessario più viola?
  5. come posso ottenere il PID di yes?
  6. posso ottenere un elenco di file "attivi"?
  7. condizioni di gara molto interessanti sul filtraggio tramite fd4, può essere evitato?
  8. yes si interromperà solo quando I exec 5>&-?
  9. importa se chiudo con >&- o <&-?

Mi fermo qui, per ora.

Grazie!

PS: parziali (numerati) le risposte sono bene .. Metto insieme i diversi pezzi e bocconi me .. (anche se una risposta esauriente da una sola persona sarebbe impressionante!)

risposta

13

fd3 sembra per ottenere "esaurito" dopo "consumo", viene automaticamente chiuso anche dopo il primo utilizzo?

No, non è chiuso. Ciò è dovuto al modo in cui funziona exec. Nella modalità in cui è stato utilizzato exec (senza argomenti), la sua funzione è di organizzare i descrittori di file della shell come richiesto dai reindirizzamenti I/O specificati a se stesso, e quindi lasciarli in questo modo finché lo script non termina o sono cambiati più tardi.

Successivamente, cat riceve una copia di questo descrittore di file 3 sul suo input standard (file descriptor 0). Lo standard input cat si chiude implicitamente quando si chiude cat (o forse, sebbene improbabile, cat lo chiuda prima che esista, ma non importa). La copia originale di questo file, che è il descrittore di file della shell 3, rimane. Anche se il file attuale ha raggiunto EOF e non ne verrà letto altro.

come è diverso fd3 da una named pipe?(Qualcosa che ho guardato già)

<(some command) sintassi della shell (che non è la sintassi bourne shell di serie e credo che è disponibile solo in zsh e bash, tra l'altro) potrebbe effettivamente essere implementato utilizzando named pipe. Probabilmente non è sotto Linux perché c'è un modo migliore (usando /dev/fd), ma probabilmente è su altri sistemi operativi.

Quindi in questo senso, questa sintassi può o non può essere un aiuto per l'impostazione di named pipe.

quando esattamente si avvia il comando yes? su dichiarazione FD? dopo?

Appena il costrutto <(yes violet) viene valutata (che avviene quando il exec 5< <(yes violet) è valutata).

si ferma (CTRL-Z o altro) e si riavvia quando è necessario più viola?

No, non si ferma. Tuttavia, bloccherà presto quando inizierà a produrre più output rispetto a qualsiasi altra cosa che sta leggendo l'altra estremità del pipe. In altre parole, il buffer delle pipe si riempirà.

come posso ottenere il PID di sì?

Buona domanda! $! sembra contenerlo immediatamente dopo l'esecuzione di yes. Comunque sembra che ci sia una subshell intermedia e tu in effetti ottieni il pid di quella subshell. Prova <(exec yes violet) per evitare il processo intermedio.

è possibile ottenere un elenco di file "attivi"?

Non dal guscio. Ma se stai usando un sistema operativo come Linux che ha /proc, puoi semplicemente consultare /proc/self/fd.

condizioni di gara molto interessanti sul filtraggio tramite fd4, può essere evitato?

Per evitarlo, si presume che si desideri attendere il completamento del processo grep prima di procedere attraverso lo script. Se si ottiene l'ID di processo di tale processo (come sopra), penso che si dovrebbe essere in grado di wait per esso.

si arresta solo quando eseguo 5> & -?

Sì. Quello che succederà allora è che yes continuerà a provare a produrre l'output per sempre ma quando l'altra estremità del descrittore di file è chiusa, otterrà un errore di scrittura (EPIPE) o un segnale (SIGPIPE) che è fatale per impostazione predefinita.

importa se chiudo con> & - o < & -?

No. Entrambe le sintassi sono disponibili per motivi di coerenza.

+0

'1.' ottiene _closed_ da' cat', ah-a! '2.' gotcha' 3.' e '4.' questo non sembra mai" bloccare e aspettare "? 'exec 3 <<(while true; do date '+% H-% M-% S' | tee -a/tmp/log; sleep 1; done); tail -f/tmp/log' '6.' shame! :('7.' mi hai insegnato come' wait' !! 'sleep 5 & pid = $ !; echo before; wait $ pid; echo after' - love it! ** RISPOSTA IMPRESSIONANTE ** !! ** GRAZIE * * !!!! – Robottinosino

+1

Re: "questo non sembra mai bloccare e attendere". Potrebbe bloccarsi alla fine ... quando il kernel decide che ha bufferizzato abbastanza dati nella pipe.Ho cambiato il tuo esempio in modo che venga emesso un po 'di testo spazzatura ogni volta attraverso il ciclo (solo per farlo andare più veloce), e per me è bloccato quando il file '/ tmp/log' deve essere di circa 48 kilobyte. Con solo' date' +% H-% M-% S'' dovrebbe ancora succedere, ci vorrà più tempo :-) – Celada

+0

** D'oro **. Sei ☆ l'uomo ☆ – Robottinosino

Problemi correlati