De temps en temps je dois spécifier un « chemin équivalent » d'un des flux IO standard ( stdin
, stdout
, stderr
). Depuis 99% du temps que je travaille avec Linux, je prévois juste /dev/
d’obtenir /dev/stdin
, etc., et cela " semble bien faire". Mais, d’une part, j’ai toujours été inquiet face à un tel raisonnement (parce que, bien sûr, "cela semble fonctionner" jusqu’à ce que cela ne fonctionne pas). De plus, je n'ai aucune idée de la portabilité de cette manœuvre.
J'ai donc quelques questions:
Dans le contexte de Linux, est - il sûr (oui / non) à assimiler
stdin
,stdout
etstderr
avec/dev/stdin
,/dev/stdout
et/dev/stderr
?Plus généralement, cette équivalence est-elle "suffisamment portable "?
Je n'ai trouvé aucune référence POSIX.
Réponses:
Il a été disponible sous Linux dans sa préhistoire. Ce n'est pas POSIX, bien que de nombreux shells (y compris AT & T
ksh
etbash
) le simulent s'il n'est pas présent dans le système d'exploitation; notez que cette simulation ne fonctionne qu'au niveau du shell (c'est-à-dire un paramètre de redirection ou de ligne de commande, et non comme un argument explicite, par exempleopen()
). Cela dit, il devrait être disponible sur la plupart des systèmes Unix commerciaux, d’une manière ou d’une autre (il est parfois orthographié/dev/fd/N
pour différents entiersN
, mais la plupart des systèmes avec celui-ci fournissent des liens symboliques comme Linux et * BSD).la source
/dev/std{in,out,err}
sont spécifiquement répertoriés comme ne faisant pas partie de la norme POSIX.1-2008 .ash
ne supporte pas/dev/stdout
dans initrd ( git.razvi.ro/… )les
/dev/std{in,out,err}
fichiers ne sont normalement que des liens symboliques vers/proc/self/fd/{0,1,2}
(respectivement). En tant que tel, rien n’est gagné par l’utilisation de méthodes définies par POSIX.Si vous souhaitez être conforme à POSIX, le meilleur moyen de le faire est d'utiliser la redirection de sortie. La redirection de la sortie shell est définie dans la norme POSIX . De plus, les numéros de descripteur de fichier STDIN, STDOUT, STDERR font également partie de POSIX .
En bref, des choses comme
>&2
sont garantis pour fonctionner.Il est toutefois important de noter que l’utilisation de STDIN, STDOUT et STDERR est subjective par rapport au démarrage du programme. Si le programme a été démarré avec le descripteur de fichier 1 comme un descripteur ouvert de fichier, votre programme doit simplement l'accepter. Même si le programme était ouvert
/dev/stdout
, tout ce qu'il ferait serait d'ouvrir le descripteur de fichier 1 qui va toujours pointer vers ce fichier.Si c'est ce que vous essayez de contourner, vous devez ouvrir le TTY directement. Normalement, sans aucune redirection, STDIN, STDOUT et STDERR ne sont que des descripteurs de fichiers ouverts pointant vers le même TTY. Il n'y a absolument rien de plus que cela.
la source
/proc/self/fd/1
ou/dev/fd/1
font partie de POSIX?/dev/std???
ne sont que des liens symboliques/proc/self/fd
sur Linux.POSIX 7 dit que ce sont des extensions.
Définitions de base , section 2.1.1 Exigences:
Identifié par le code HTML POSIX: où se trouve la liste des fonctions de l’API C POSIX?
Également assez étrange, l'
uuencode
outil donne/dev/stdout
un effet magique :La documentation du noyau Linux indique que tous les systèmes devraient l’avoir.
https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.rst
Je ne pouvais cependant pas trouver où ces liens symboliques sont créés dans le noyau (distribution fournie?).
la source
/ dev / {stdout, stdin, stderr} fonctionne dans Bash sur ces plateformes:
Mais échoue en csh sur ceux-ci:
la source
bash
est spécial car il peut être compilé pour gérer/dev/fd/x
par lui-même pour les redirections sur les systèmes qui n'ont pas/dev/fd
Un problème avec
/dev/stdout
et amis est que vous pouvez ne pas avoir la permission de leur écrire dans certaines circonstances. Par exemple, je l’ai rencontré lors de l’appel de scripts à partir de Nix , et j’imagine des outils similaires qui exécutent des scripts dans des jails / sandboxes / containers / VMs / etc. peut rencontrer des problèmes similaires.En utilisant une syntaxe comme "
1>&2
travaillée" dans ces cas-là, et puisque je savais que je fonctionnerais sous Bash, je pouvais utiliser la substitution de processus pour les commandes qui attendent des noms de fichiers.la source