Chiusura di un descrittore di file,> & - vs <& -


49

Nel tutorial di bash che sto leggendo, dice che se apri un descrittore di file per la lettura, ad es

exec 3< echolist

Quindi devi chiuderlo in questo modo,

exec 3<&-

Tuttavia, se si apre un descrittore di file per la scrittura, deve essere chiuso in questo modo:

exec 3>&-

Tuttavia, quando guardo su Internet, vedo le persone aprire i file e quindi chiuderli con questo:

exec 3>&- 

NOTA: quando, secondo il tutorial, dovrebbero essere in uso exec 3<&1.

Quindi la mia domanda è: tutti i descrittori di file possono essere chiusi tramite exec n>&-dove n è il numero del descrittore di file? Indipendentemente se è stato aperto per la lettura, la scrittura o entrambi?


21
L'unica differenza tra >&-e <&-è il valore predefinito fd quando non specificato ( >&-is 1>&-while <&-is 0<&-). Lo stesso per x>&ycui è uguale a x<&yquando xnon viene fornito.
Stéphane Chazelas,

Risposte:


48

Puoi chiudere il descrittore di file usando entrambi <&-e >&-, bashanalizzerà due sintassi uguali.

Dal file y.tab.c nel bashcodice sorgente:

5385   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */                
5386   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
5387     return (character);

2
Questo può essere usato anche sui <>descrittori di file.
CMCDragonkai,

1
No, non è possibile, ma come in 3>&-o 3<&-sembra chiudere il descrittore.
CMCDragonkai,

1
Tale chiusura <>può essere effettuata con le stesse modalità.
CMCDragonkai,

1
Non riesco a capire cosa intendi. Per favore
fai

1
Non penso sia quello che volevo dire. Solo che un descrittore di file di lettura / scrittura può essere chiuso usando anche 3> & - e 3 <& -.
CMCDragonkai,

15

Per quanto posso vedere, exec 3>&-e exec 3<&-sono gli stessi e può essere utilizzato su qualsiasi descrittore di file, indipendentemente da come è stato aperto. Secondo le sezioni 2.7.6 e 2.7.5 della definizione POSIX del linguaggio di comando Shell :

2.7.5 Duplicazione di un descrittore di file di input

L'operatore di reindirizzamento:

[N] <& parola

[... SNIP ...]

Se la parola restituisce '-', il descrittore di file n o l'input standard se n non è specificato, devono essere chiusi. I tentativi di chiudere un descrittore di file non aperto non devono costituire un errore. Se la parola restituisce qualcos'altro, il comportamento non è specificato.

2.7.6 Duplicazione di un descrittore di file di output

L'operatore di reindirizzamento:

[N]> & parola

[... SNIP ...]

Se la parola restituisce '-', il descrittore di file n o l'output standard se n non è specificato, viene chiuso. I tentativi di chiudere un descrittore di file non aperto non devono costituire un errore. Se la parola restituisce qualcos'altro, il comportamento non è specificato.

Si noti che nessuno dei due specifica nulla su come il descrittore di file n è stato aperto originariamente. Ciò è in linea con il fatto che close (2) non si preoccupa di come hai aperto il file.

Una breve sequenza di quanto segue:

exec 3< /etc/passwd
exec 4> foo
exec 3<&-
exec 4<&-

contro questo:

exec 3< /etc/passwd
exec 4> foo
exec 3<&-
exec 4>&-

mostra che in entrambi i casi, Bash fa esattamente la stessa cosa.

Due fatti lievemente interessanti


1
La pagina man di bash menziona la chiusura, citando il tuo link: Se la parola restituisce '-', il descrittore di file n viene chiuso.
Studog

@studog Grazie per aver verificato la fonte! Penso che quello che è successo qui sia che stavo guardando una manpage locale per Bash 3, e quindi collegata alla documentazione online, che era per Bash 4. Nella vecchia documentazione di Bash 3, la frase sulla chiusura è stata omessa dalla descrizione di [N]>&WORD: git .savannah.gnu.org / cgit / bash.git / tree / doc /…
Steven D

7

Un esempio per la comprensione di cuonglm della chiusura di un '<>' FD.

Questo è citato dalla Guida avanzata di script Bash su http://tldp.org/LDP/abs/html/io-redirection.html

[j]<>filename
  #  Open file "filename" for reading and writing,
  #+ and assign file descriptor "j" to it.
  #  If "filename" does not exist, create it.
  #  If file descriptor "j" is not specified, default to fd 0, stdin.
  #
  #  An application of this is writing at a specified place in a file. 
  echo 1234567890 > File    # Write string to "File".
  exec 3<> File             # Open "File" and assign fd 3 to it.
  read -n 4 <&3             # Read only 4 characters.
  echo -n . >&3             # Write a decimal point there.
  exec 3>&-                 # Close fd 3.
  cat File                  # ==> 1234.67890
  #  Random access, by golly.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.