Bash scripting - file descriptor: differenze tra le versioni

m
nessun oggetto della modifica
mNessun oggetto della modifica
mNessun oggetto della modifica
Riga 1: Riga 1:
{{Bash_scripting}}
{{Bash_scripting}}
=File descriptor=
__TOC__
Su Unix e Unix-like ogni processo che non è avviato in background ha di default tre '''file descriptor''', nella forma di identificativi interi:
Su Unix e Unix-like ogni processo che non è avviato in background ha di default tre '''file descriptor''', nella forma di identificativi interi:
* 0 ('''stdin'''), lo ''standard input'', da cui si leggono gli input (di default quanto scritto dalla tastiera sul terminale associato);
* 0 ('''stdin'''), lo ''standard input'', da cui si leggono gli input (di default quanto scritto dalla tastiera sul terminale associato);
Riga 9: Riga 9:
Si chiamano ''file descriptor'' perché sono identificativi che fanno riferimento a un file; e infatti perfino i dispositivi, anche virtuali come il terminale, sono considerati dei file. Questo permette la possibilità di associare in modo trasparente questi file descriptor standard anche a file qualsiasi, oltre che ad altri file descriptor, in modo da ridirigerne il contenuto.  E disporre di due diversi file descriptor per l'output prodotto da un comando e i messaggi di errore, permette di disabilitare anche solo uno dei due, o di salvarli su due file diversi.
Si chiamano ''file descriptor'' perché sono identificativi che fanno riferimento a un file; e infatti perfino i dispositivi, anche virtuali come il terminale, sono considerati dei file. Questo permette la possibilità di associare in modo trasparente questi file descriptor standard anche a file qualsiasi, oltre che ad altri file descriptor, in modo da ridirigerne il contenuto.  E disporre di due diversi file descriptor per l'output prodotto da un comando e i messaggi di errore, permette di disabilitare anche solo uno dei due, o di salvarli su due file diversi.


==Redirezioni==
== Redirezioni ==
Alcune comuni redirezioni, da scriversi dopo un comando (la stringa ''file'' può essere anche una variabile quotata):
Alcune comuni redirezioni, da scriversi dopo un comando (la stringa ''file'' può essere anche una variabile quotata):
* '''< file''' collega lo standard input al file, in modo da leggerne il contenuto. Il file descriptor è implicito, ma sarebbe equivalente scrivere '''0< file''';
* '''< file''' collega lo standard input al file, in modo da leggerne il contenuto. Il file descriptor è implicito, ma sarebbe equivalente scrivere '''0< file''';
Riga 17: Riga 17:
* '''>&2''' scrive lo standard output sullo standard error. Il file descriptor dello standard output è implicito, mentre quello alla destra dev'essere preceduto da <code>&</code>, ma sarebbe equivalente scrivere '''1>&2''';
* '''>&2''' scrive lo standard output sullo standard error. Il file descriptor dello standard output è implicito, mentre quello alla destra dev'essere preceduto da <code>&</code>, ma sarebbe equivalente scrivere '''1>&2''';
* '''2>&1''' scrive lo standard error sullo standard output;
* '''2>&1''' scrive lo standard error sullo standard output;
* '''&> file''' (non ''POSIX'', abbreviazione per: '''> file 2>&1''') invia standard output ed error sul file (con ''append'': '''&>> file''');
* '''&> file''' (non [[POSIX]], abbreviazione per: '''> file 2>&1''') invia standard output ed error sul file (con ''append'': '''&>> file''');
* '''<&-''' chiude lo standard input. Il file descriptor è implicito, ma sarebbe equivalente scrivere '''0<&-''';
* '''<&-''' chiude lo standard input. Il file descriptor è implicito, ma sarebbe equivalente scrivere '''0<&-''';
* '''>&-''' chiude lo standard output. Il file descriptor è implicito, ma sarebbe equivalente scrivere '''1>&-''';
* '''>&-''' chiude lo standard output. Il file descriptor è implicito, ma sarebbe equivalente scrivere '''1>&-''';
Riga 37: Riga 37:
Una pipe (nella forma: <code>comando1 '''|''' comando2</code>) è anch'essa una forma di redirezione, già trattata in una sezione sulle [[Bash scripting - istruzioni composte#Composizione di comandi con pipe | istruzioni composte]], in cui lo standard output di ''comando1'' è rediretto sullo standard input di ''comando2''.
Una pipe (nella forma: <code>comando1 '''|''' comando2</code>) è anch'essa una forma di redirezione, già trattata in una sezione sulle [[Bash scripting - istruzioni composte#Composizione di comandi con pipe | istruzioni composte]], in cui lo standard output di ''comando1'' è rediretto sullo standard input di ''comando2''.


===Redirezioni "here document/string"===
=== Redirezioni "here document/string" ===
Delle redirezioni particolari dallo standard input sono possibili anche nelle forme:
Delle redirezioni particolari dallo standard input sono possibili anche nelle forme:
* '''<<parola''' (''here-document''): legge tutte le righe che seguono, finché ne incontra una corrispondente alla parola scelta, e le invia allo standard input di un comando. Nel testo inviato si applicano le espansioni delle stringhe quotate, e come se tutto il testo fosse quotato, ma le virgolette non sono considerate un carattere speciale (restano: <code>$ \ `</code>, con <code>\</code> a fare da carattere di escape). Se invece la parola è racchiusa tra apici o virgolette (per esempio: '''<<"parola"'''), si annullano tutte le espansioni fino alla chiusura di ''here-document''. Il file descriptor è implicito, ma è equivalente scrivere '''0<<parola''';
* '''<<parola''' (''here-document''): legge tutte le righe che seguono, finché ne incontra una corrispondente alla parola scelta, e le invia allo standard input di un comando. Nel testo inviato si applicano le espansioni delle stringhe quotate, e come se tutto il testo fosse quotato, ma le virgolette non sono considerate un carattere speciale (restano: <code>$ \ `</code>, con <code>\</code> a fare da carattere di escape). Se invece la parola è racchiusa tra apici o virgolette (per esempio: '''<<"parola"'''), si annullano tutte le espansioni fino alla chiusura di ''here-document''. Il file descriptor è implicito, ma è equivalente scrivere '''0<<parola''';
Riga 65: Riga 65:
Pipe e altre concatenazioni da aggiungere al comando utilizzante la redirezione ''here-document'' vanno scritte sulla stessa riga del comando. E, se è possibile scrivere il comando su più righe, quella successiva al comando è considerata la riga dopo la parola che chiude tutto il testo usato per la redirezione ''here-document''.
Pipe e altre concatenazioni da aggiungere al comando utilizzante la redirezione ''here-document'' vanno scritte sulla stessa riga del comando. E, se è possibile scrivere il comando su più righe, quella successiva al comando è considerata la riga dopo la parola che chiude tutto il testo usato per la redirezione ''here-document''.


===Scope della redirezione===
=== Scope della redirezione ===
Si noti che lo ''scope'' (il raggio d'azione) della redirezione non serve soltanto per evitare di scrivere più volte il percorso del file, ma ne influenza anche il significato. In particolare con la redirezione dello standard input (lettura), per garantire che tutte le istruzioni continuino la lettura da dove era rimasta invece che riprenderla sempre dall'inizio, e dello standard output, per garantire che il file non venga troncato da ogni comando ma che i successivi continuino a scrivere in seguito (come se usassero la redirezione con ''append'').
Si noti che lo ''scope'' (il raggio d'azione) della redirezione non serve soltanto per evitare di scrivere più volte il percorso del file, ma ne influenza anche il significato. In particolare con la redirezione dello standard input (lettura), per garantire che tutte le istruzioni continuino la lettura da dove era rimasta invece che riprenderla sempre dall'inizio, e dello standard output, per garantire che il file non venga troncato da ogni comando ma che i successivi continuino a scrivere in seguito (come se usassero la redirezione con ''append'').


Riga 106: Riga 106:
Si noti invece che utilizzando sempre la redirezione <code>></code> per tre volte di fila, si scriverebbe il file sempre dall'inizio, con il risultato che solo l'ultima variabile sarebbe presente nel file al termine delle istruzioni.
Si noti invece che utilizzando sempre la redirezione <code>></code> per tre volte di fila, si scriverebbe il file sempre dall'inizio, con il risultato che solo l'ultima variabile sarebbe presente nel file al termine delle istruzioni.


==Nuovi file descriptor==
== Nuovi file descriptor ==
In aggiunta ai tre file descriptor standard, è possibile aprirne di nuovi, in lettura (<code>FD<...</code>...), in scrittura (<code>FD>...</code>, append: <code>FD>>...</code>) e in lettura/scrittura (<code>FD<>...</code>), dove FD è un intero rappresentante il nuovo file descriptor e al posto dei puntini può esserci sia un file sia un file descriptor già esistente preceduto dal carattere <code>&</code>.
In aggiunta ai tre file descriptor standard, è possibile aprirne di nuovi, in lettura (<code>FD<...</code>...), in scrittura (<code>FD>...</code>, append: <code>FD>>...</code>) e in lettura/scrittura (<code>FD<>...</code>), dove FD è un intero rappresentante il nuovo file descriptor e al posto dei puntini può esserci sia un file sia un file descriptor già esistente preceduto dal carattere <code>&</code>.


Riga 142: Riga 142:
Finché un file descriptor non è chiuso, non è garantita la scrittura sul file, ma la scrittura tramite file descriptor è più efficiente.
Finché un file descriptor non è chiuso, non è garantita la scrittura sul file, ma la scrittura tramite file descriptor è più efficiente.


===Salvare i file descriptor===
=== Salvare i file descriptor ===
Si noti che <code>exec</code> è equivalente a una redirezione in un blocco, ma la chiusura dei file descriptor aperti dev'essere gestita manualmente. Prima di cambiare quelli standard, per consentirne il successivo ripristino al loro valore originale, vanno salvati in un nuovo file descriptor temporaneo:
Si noti che <code>exec</code> è equivalente a una redirezione in un blocco, ma la chiusura dei file descriptor aperti dev'essere gestita manualmente. Prima di cambiare quelli standard, per consentirne il successivo ripristino al loro valore originale, vanno salvati in un nuovo file descriptor temporaneo:
<pre>
<pre>
6 999

contributi