GNU/Linux >> Linux Esercitazione >  >> Linux

Significato dei simboli delle frecce nella duplicazione/chiusura dei descrittori di file in Bash?

Sto leggendo un libro sulla riga di comando di Linux in cui l'autore non sembra seguire le convenzioni nel manuale di bash per quanto riguarda i simboli delle frecce utilizzati nelle operazioni di reindirizzamento. Vale a dire, usa sempre la freccia sinistra < nella duplicazione e chiusura dei descrittori di file indipendentemente dal fatto che i descrittori siano di input o di output.

Ecco un esempio:

exec 3<&0 4<&1 #shouldn't be 4>&1 ?
#...
exec 3<&- 4<&- #shouldn't be 4>&- ?

La pagina man di Bash è vaga a questo punto, in base ad essa, i descrittori di file di duplicazione/chiusura e spostamento hanno le seguenti sintassi:

#Duplicating and closing (in case word expands to -):
[n]<&word 
[n]>&word

#Moving:
[n]<&digit-
[n]>&digit-

Sono descritti per avere un comportamento diverso solo se non forniamo esplicitamente il n . Ma quando lo facciamo, significa che possiamo usare queste forme in modo intercambiabile?

Risposta accettata:

Non importa perché sia ​​4>&1 e 4<&1 fai la stessa cosa:dup2(1, 4) che è la chiamata di sistema per duplicare un fd su un altro. L'FD duplicato eredita automaticamente la direzione I/O dell'FD originale. (lo stesso per 4>&- rispetto a 4<&- che entrambi risolvono in close(4) e 4>&1- che è il dup2(1, 4) seguito da close(1) ).

Tuttavia, il 4<&1 la sintassi crea confusione a meno che per qualche motivo fd 1 non fosse esplicitamente aperto per la lettura (il che sarebbe ancora più confuso), quindi nella mia mente dovrebbe essere evitato.

Il duplicato fd condivide la stessa descrizione del file aperto il che significa che condividono lo stesso offset nel file (per quei tipi di file in cui ha senso) e gli stessi flag associati (modalità di reindirizzamento/apertura I/O, O_APPEND e così via).

Su Linux, c'è un altro modo per duplicare un fd (che in realtà non è una duplicazione) e crea una nuova descrizione del file aperto per la stessa risorsa ma con possibili flag diversi.

exec 3> /dev/fd/4

Mentre su Solaris e probabilmente la maggior parte degli altri Unice, è più o meno equivalente a dup2(4, 3) , su Linux, che apre da zero la stessa risorsa indicata da fd 4.

Questa è una differenza importante, perché ad esempio, per un file normale, l'offset di fd 3 sarà 0 (l'inizio del file) e il file verrà troncato (motivo per cui ad esempio su Linux è necessario scrivere tee -a /dev/stderr invece di tee /dev/stderr ).

Correlati:come dire a Firefox di utilizzare un altro dispositivo ALSA?

E la modalità I/O può essere diversa.

È interessante notare che se fd 4 puntava all'estremità di lettura di una pipe, allora fd 3 ora punta all'estremità di scrittura (/dev/fd/3 si comporta come una pipe denominata ):

$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b

$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b

Linux
  1. Trucchi Bash più stupidi:variabili, trova, descrittori di file e operazioni remote

  2. Uno script Bash può essere agganciato a un file?

  3. Il Bash '?

  4. Eseguire operazioni di scrittura atomica in un file in Bash?

  5. Script Bash:controlla se un file è un file di testo?

Bash:aggiungi al file

Come reindirizzare stderr a stdout in Bash

Sostituzione di String in Bash

35 Esempi di script Bash

Bash Scripting – Dichiarazioni condizionali

Scripting Bash(III)