GNU/Linux >> Tutoriels Linux >  >> Linux

>&- est-il plus efficace que>/dev/null ?

Hier, j'ai lu ce commentaire SO qui dit que dans le shell (au moins bash ) >&- "a le même résultat que" >/dev/null .

Ce commentaire fait en fait référence au guide ABS comme source de ses informations. Mais cette source dit que le >&- syntaxe "ferme les descripteurs de fichiers".

Il ne m'est pas clair si les deux actions consistant à fermer un descripteur de fichier et à le rediriger vers le périphérique nul sont totalement équivalentes. Donc ma question est :le sont-ils ?

À première vue, il semble que fermer un descripteur, c'est comme fermer une porte, mais le rediriger vers un périphérique nul, c'est ouvrir une porte vers les limbes ! Les deux ne me semblent pas exactement identiques, car si je vois une porte fermée, je n'essaierai pas d'en jeter quoi que ce soit, mais si je vois une porte ouverte, je supposerai que je peux.

En d'autres termes, je me suis toujours demandé si >/dev/null signifie que cat mybigfile >/dev/null traiterait en fait chaque octet du fichier et l'écrirait dans /dev/null qui l'oublie. D'un autre côté, si le shell rencontre un descripteur de fichier fermé, j'ai tendance à penser (mais je ne suis pas sûr) qu'il n'écrira tout simplement rien, bien que la question reste de savoir si cat va encore lire chaque octet.

Ce commentaire dit >&- et >/dev/null "devrait ” être le même, mais ce n'est pas une réponse si retentissante pour moi. J'aimerais avoir une réponse plus autoritaire avec une référence au noyau standard ou source ou non…

Réponse acceptée :

Non, certainement pas souhaitez fermer les descripteurs de fichiers 0, 1 et 2.

Si vous le faites, la première fois que l'application ouvrira un fichier, il deviendra stdin/stdout/stderr…

Par exemple, si vous faites :

echo text | tee file >&-

Quand tee (au moins certaines implémentations, comme busybox') ouvre le fichier en écriture, il sera ouvert sur le descripteur de fichier 1 (stdout). Alors tee écrira text deux fois dans 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)                           = ?

Cela a été connu pour causer des vulnérabilités de sécurité. Par exemple :

chsh 2>&-

Et chsh (une application setuid) peut finir par écrire des messages d'erreur dans /etc/passwd .

Certains outils et même certaines bibliothèques essaient de s'en prémunir. Par exemple GNU tee déplacera le descripteur de fichier vers un au-dessus de 2 si les fichiers qu'il ouvre pour l'écriture sont assignés 0, 1, 2 tandis que busybox tee ne le fera pas.

En relation :Linux - Quel est le fichier par défaut pour `hostname` ?

La plupart des outils, s'ils ne peuvent pas écrire sur stdout (parce que, par exemple, il n'est pas ouvert), signaleront un message d'erreur sur stderr (dans la langue de l'utilisateur, ce qui signifie un traitement supplémentaire pour ouvrir et analyser les fichiers de localisation…), il sera donc être nettement moins efficace et éventuellement entraîner l'échec du programme.

Dans tous les cas, ce ne sera pas plus efficace. Le programme fera toujours un write() appel système. Cela ne peut être que plus efficace si le programme abandonne l'écriture sur stdout/stderr après le premier échec write() appel système, mais les programmes ne le font généralement pas. Ils quittent généralement avec une erreur ou continuent d'essayer.


Linux
  1. Comment Linux gère-t-il plusieurs séparateurs de chemins consécutifs (/home////nom d'utilisateur///fichier) ?

  2. Quelle est la portabilité de /dev/stdin, /dev/stdout et /dev/stderr ?

  3. Quand utiliser /dev/random contre /dev/urandom ?

  4. Comment désactiver complètement un Cronjob vers /dev/null/?

  5. Comment encoder en base64 /dev/random ou /dev/urandom ?

/dev/null sous Linux

DD de /dev/zero à /dev/null...ce qui se passe réellement

/dev/sdb :aucun fichier ou répertoire de ce type (mais /dev/sdb1, etc. existe)

Linux :Différence entre /dev/console , /dev/tty et /dev/tty0

noyau :désactiver /dev/kmem et /dev/mem

Créer un périphérique de bloc virtuel qui écrit dans /dev/null