GNU/Linux >> Linux Esercitazione >  >> Linux

>&- è più efficiente di>/dev/null?

Ieri ho letto questo commento SO che dice che nella shell (almeno bash ) >&- "ha lo stesso risultato di" >/dev/null .

Tale commento si riferisce in realtà alla guida dell'ABS come fonte delle sue informazioni. Ma quella fonte dice che il >&- sintassi "chiude i descrittori di file".

Non mi è chiaro se le due azioni di chiudere un descrittore di file e reindirizzarlo al dispositivo nullo siano totalmente equivalenti. Quindi la mia domanda è:lo sono?

A prima vista sembra che chiudere un descrittore sia come chiudere una porta, ma reindirizzarlo a un dispositivo nullo sia aprire una porta per il limbo! I due non mi sembrano esattamente la stessa cosa perché se vedo una porta chiusa non cercherò di buttarci fuori niente, ma se vedo una porta aperta presumo di poterlo fare.

In altre parole, mi sono sempre chiesto se >/dev/null significa che cat mybigfile >/dev/null elaborerebbe effettivamente ogni byte del file e lo scriverebbe in /dev/null che lo dimentica. D'altra parte, se la shell incontra un descrittore di file chiuso, tendo a pensare (ma non sono sicuro) che semplicemente non scriverà nulla, anche se rimane la domanda se cat continuerà a leggere ogni byte.

Questo commento dice >&- e >/dev/nulldovrebbe ” essere lo stesso, ma non è una risposta così clamorosa per me. Mi piacerebbe avere una risposta più autorevole con qualche riferimento al core standard o sorgente o meno...

Risposta accettata:

No, certamente non vuoi chiudere i descrittori di file 0, 1 e 2.

Se lo fai, la prima volta che l'applicazione apre un file, diventerà stdin/stdout/stderr…

Ad esempio, se lo fai:

echo text | tee file >&-

Quando tee (almeno alcune implementazioni, come busybox') apre il file per la scrittura, sarà aperto sul descrittore di file 1 (stdout). Quindi tee scriverà text due volte in file :

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "textn", 8193)                 = 5
write(1, "textn", 5)                   = 5
write(1, "textn", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

Questo è noto per causare vulnerabilità di sicurezza. Ad esempio:

chsh 2>&-

E chsh (un'applicazione setuid) potrebbe finire per scrivere messaggi di errore in /etc/passwd .

Alcuni strumenti e persino alcune librerie cercano di proteggersi da questo. Ad esempio GNU tee sposterà il descrittore di file su uno sopra 2 se i file che apre per la scrittura sono assegnati 0, 1, 2 mentre busybox tee non lo farà.

Correlati:Linux – Qual è il file predefinito per `hostname`?

La maggior parte degli strumenti, se non possono scrivere su stdout (perché ad esempio non è aperto), segnaleranno un messaggio di errore su stderr (nella lingua dell'utente che significa elaborazione extra per aprire e analizzare i file di localizzazione...), quindi lo farà essere significativamente meno efficiente e possibilmente causare il fallimento del programma.

In ogni caso, non sarà più efficiente. Il programma eseguirà comunque un write() chiamata di sistema. Può essere più efficiente solo se il programma smette di scrivere su stdout/stderr dopo il primo write() fallito chiamata di sistema, ma i programmi generalmente non lo fanno. Generalmente escono con un errore o continuano a provare.


Linux
  1. In che modo Linux gestisce più separatori di percorsi consecutivi (/home////nomeutente///file)?

  2. Linux:differenza tra /dev/console , /dev/tty e /dev/tty0?

  3. Quanto sono portatili /dev/stdin, /dev/stdout e /dev/stderr?

  4. Cosa sono i file /dev/zero e /dev/null in Linux

  5. Come codificare in base64 /dev/random o /dev/urandom?

/dev/null in Linux

Quando dovrei usare /dev/shm/ e quando dovrei usare /tmp/?

DD da /dev/zero a /dev/null... cosa succede realmente

Come Linux usa /dev/tty e /dev/tty0

echo o print /dev/stdin /dev/stdout /dev/stderr

Perché sono necessari < o > per usare /dev/tcp