Dans quelle mesure les fichiers / dev / stdin, / dev / stdout et / dev / stderr sont-ils portables?

55

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:

  1. Dans le contexte de Linux, est - il sûr (oui / non) à assimiler stdin, stdoutet stderravec /dev/stdin, /dev/stdoutet /dev/stderr?

  2. Plus généralement, cette équivalence est-elle "suffisamment portable "?

Je n'ai trouvé aucune référence POSIX.

kjo
la source

Réponses:

36

Il a été disponible sous Linux dans sa préhistoire. Ce n'est pas POSIX, bien que de nombreux shells (y compris AT & T kshet bash) 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 exemple open()). 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/Npour différents entiers N, mais la plupart des systèmes avec celui-ci fournissent des liens symboliques comme Linux et * BSD).

geekosaur
la source
13
En effet, ils /dev/std{in,out,err}sont spécifiquement répertoriés comme ne faisant pas partie de la norme POSIX.1-2008 .
jw013
Il semble que ashne supporte pas /dev/stdoutdans initrd ( git.razvi.ro/… )
CMCDragonkai
@CMCDragonkai: Ce n'est pas un / dev / stdout pouvant être géré par le shell, et qu'attendiez-vous de initrd? Il manque la plupart des commodités pour le rendre aussi petit que pratique.
Josué
22

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 >&2sont 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.

Patrick
la source
2
+1, en particulier pour la partie "une chose importante"; Je vais digérer cela en plusieurs parties :)
Alois Mahdal
4
Pouvez - vous préciser si /proc/self/fd/1ou /dev/fd/1font partie de POSIX?
Steven Penny
/dev/std???ne sont que des liens symboliques /proc/self/fdsur Linux.
Stéphane Chazelas
5

POSIX 7 dit que ce sont des extensions.

Définitions de base , section 2.1.1 Exigences:

Le système peut fournir des extensions non standard. Ces fonctionnalités ne sont pas requises par POSIX.1-2008 et peuvent inclure, sans toutefois s'y limiter:

[...]

  • D' autres fichiers caractère spéciaux avec des propriétés spéciales (par exemple,  /dev/stdin,  /dev/stdoutet  /dev/stderr)

Identifié par le code HTML POSIX: où se trouve la liste des fonctions de l’API C POSIX?

Également assez étrange, l' uuencodeoutil donne /dev/stdoutun effet magique :

Spécifier un opérande decode_pathname de /dev/stdout doit indiquer que uudecode doit utiliser la sortie standard.

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

Compulsory links
These links should exist on all systems:
/dev/fd       /proc/self/fd   symbolic   File descriptors
/dev/stdin    fd/0            symbolic   stdin file descriptor
/dev/stdout   fd/1            symbolic   stdout file descriptor
/dev/stderr   fd/2            symbolic   stderr file descriptor

Je ne pouvais cependant pas trouver où ces liens symboliques sont créés dans le noyau (distribution fournie?).

Ciro Santilli 改造 中心 六四 事件
la source
1

/ dev / {stdout, stdin, stderr} fonctionne dans Bash sur ces plateformes:

Linux debian-ppc 3.16.0-4-powerpc #1 Debian 3.16.7-ckt25-1 (2016-03-06) ppc GNU/Linux
HP-UX hpux-ia6 B.11.31 U ia64 0107668277 unlimited-user license
AIX aix7 1 7 000ACFDE4C00
FreeBSD freebsd.polarhome.com 10.0-RELEASE-p7 FreeBSD 10.0-RELEASE-p7 #0: Tue Jul  8 06:37:44 UTC 2014     [email protected]:/usr/obj/usr/src/sys/GENERIC  amd64
HP-UX hpux64 B.11.11 U 9000/785 2000587908 unlimited-user license
Darwin macosx 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:26:45 PDT 2012; root:xnu-1699.32.7~1/RELEASE_I386 i386
GNU hurd 0.7 GNU-Mach 1.6-486/Hurd-0.7 i686-AT386 GNU
Linux mandriva.polarhome.com 2.6.33.7-desktop-2mnb #1 SMP Mon Sep 20 18:19:20 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
SunOS openindiana 5.11 oi_148 i86pc i386 i86pc
MirBSD miros.polarhome.com 10 Kv#10uAF-20110818 GENERIC#1330 i386
Linux pidora 3.12.23-2.20140626git25673c3.rpfr20.armv6hl.bcm2708 #1 PREEMPT Fri Jul 4 16:06:10 EDT 2014 armv6l armv6l armv6l GNU/Linux
QNX qnx 6.5.0 2010/07/09-14:44:03EDT x86pc x86
NetBSD netbsd.polarhome.com 6.1.3 NetBSD 6.1.3 (GENERIC) i386
OpenBSD openbsd.polarhome.com 4.9 GENERIC#671 i386
Linux raspbian 3.18.7+ #755 PREEMPT Thu Feb 12 17:14:31 GMT 2015 armv6l GNU/Linux
SCO_SV scosysv 5 6.0.0 i386
Linux redhat.polarhome.com 3.17.4-301.fc21.x86_64 #1 SMP Thu Nov 27 19:09:10 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
SunOS solaris-x86 5.11 11.3 i86pc i386 i86pc
Linux suse 3.4.63-2.44-desktop #1 SMP PREEMPT Wed Oct 2 11:18:32 UTC 2013 (d91a619) x86_64 x86_64 x86_64 GNU/Linux
SunOS solaris 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210
Linux ubuntu 3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:15 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
UnixWare unixware 5 7.1.4 i386 x86at SCO UNIX_SVR5
OSF1 tru64.polarhome.com V5.1 2650 alpha
Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u2 (2016-01-02) x86_64 GNU/Linux

Mais échoue en csh sur ceux-ci:

HP-UX hpux-ia6 B.11.31 U ia64 0107668277 unlimited-user license
Linux centos.polarhome.com 2.6.18-409.el5 #1 SMP Tue Mar 15 18:13:50 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
HP-UX hpux64 B.11.11 U 9000/785 2000587908 unlimited-user license
AIX aix7 1 7 000ACFDE4C00
SCO_SV scosysv 5 6.0.0 i386
SunOS solaris-x86 5.11 11.3 i86pc i386 i86pc
SunOS openindiana 5.11 oi_148 i86pc i386 i86pc
SunOS solaris 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210
UnixWare unixware 5 7.1.4 i386 x86at SCO UNIX_SVR5
OSF1 tru64.polarhome.com V5.1 2650 alpha
Ole Tange
la source
6
Quel était votre cas de test? bashest spécial car il peut être compilé pour gérer /dev/fd/xpar lui-même pour les redirections sur les systèmes qui n'ont pas/dev/fd
Stéphane Chazelas
@ StéphaneChazelas J'ai voté contre parce que je peux voir que c'est trompeur sans cette précision (pas d'offense à Ole).
Evan Carroll
0

Un problème avec /dev/stdoutet 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>&2travaillé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.

Warbo
la source