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


55

Di tanto in tanto ho bisogno di specificare un "percorso-equivalente" di uno degli standard IO flussi ( stdin, stdout, stderr). Dal 99% delle volte che lavoro con Linux, faccio semplicemente finta /dev/di ottenere /dev/stdin, ecc. E questo " sembra fare la cosa giusta". Ma, per prima cosa, sono sempre stato a disagio per una tale logica (perché, ovviamente, "sembra funzionare" fino a quando non lo fa). Inoltre, non ho buon senso per quanto portatile sia questa manovra.

Quindi ho alcune domande:

  1. Nel contesto di Linux, è sicuro (sì / no) di equiparare stdin, stdoute stderrcon /dev/stdin, /dev/stdoute /dev/stderr?

  2. Più in generale, questa equivalenza è "adeguatamente trasportabile "?

Non sono riuscito a trovare riferimenti POSIX.



Risposte:


36

È stato disponibile su Linux nella sua preistoria. E ' non POSIX, anche se molte conchiglie reali (tra cui AT & T kshe bash) simulerà se non è presente nel sistema operativo; si noti che questa simulazione funziona solo a livello di shell (ovvero reindirizzamento o parametro della riga di comando, non come argomento esplicito ad es open().). Detto questo, dovrebbe essere disponibile sulla maggior parte dei sistemi Unix commerciali, in un modo o nell'altro (a volte è scritto /dev/fd/Nper vari numeri interi N, ma la maggior parte dei sistemi con ciò fornirà collegamenti simbolici come fanno Linux e * BSD).


13
Infatti, /dev/std{in,out,err}sono specificamente elencati come non parte dello standard POSIX.1-2008 .
jw013,

Sembra che ashnon supporti /dev/stdoutin initrd ( git.razvi.ro/… )
CMCDragonkai

@CMCDragonkai: Questo non è un / dev / stdout che può essere gestito dalla shell, e cosa ti aspettavi da initrd? Manca la maggior parte delle cose per renderlo piccolo quanto pratico.
Giosuè,

22

i /dev/std{in,out,err}file sono normalmente solo collegamenti simbolici a /proc/self/fd/{0,1,2}(rispettivamente). Di conseguenza, non è stato acquisito nulla utilizzando metodi definiti POSIX.

Se si desidera essere conformi a POSIX, il modo migliore per farlo è utilizzare il reindirizzamento dell'output. Il reindirizzamento dell'output della shell è definito nello standard POSIX . Inoltre, i numeri dei descrittori di file STDIN, STDOUT, STDERR fanno parte di POSIX .
In breve, cose come >&2sono garantite per funzionare.

Una cosa importante da notare è che l'uso di STDIN, STDOUT e STDERR è soggettivo rispetto all'avvio del programma. Se il programma è stato avviato con il descrittore di file 1 come handle aperto di un file, il programma deve semplicemente accettarlo. Anche se dovessi aprire il programma /dev/stdout, tutto ciò che farebbe sarebbe aprire il descrittore di file 1 che continuerà a puntare a quel file.
Se questo è ciò che stai cercando di aggirare, devi aprire direttamente TTY. Normalmente, senza alcun reindirizzamento, STDIN, STDOUT e STDERR sono solo descrittori di file aperti che puntano allo stesso TTY. Non c'è assolutamente niente di più.


2
+1, in particolare per la parte "una cosa importante"; Ho intenzione di digerire questo in parti :)
Alois Mahdal

4
Potete chiarire se /proc/self/fd/1o /dev/fd/1fanno parte di POSIX?
Steven Penny,

/dev/std???sono solo collegamenti simbolici a /proc/self/fdsu Linux.
Stéphane Chazelas,

5

POSIX 7 afferma che sono estensioni.

Definizioni di base , Sezione 2.1.1 Requisiti:

Il sistema può fornire estensioni non standard. Queste sono funzioni non richieste da POSIX.1-2008 e possono includere, ma non sono limitate a:

[...]

  • Ulteriori file di carattere speciali con proprietà speciali (ad esempio,  /dev/stdin,  /dev/stdoute  /dev/stderr)

Trovato grepping con HTML POSIX: dov'è l'elenco delle funzioni API POSIX C?

Anche abbastanza stranamente, lo uuencodestrumento /dev/stdoutun effetto magico :

Specificare un operando decode_pathname di /dev/stdout deve indicare che uudecode deve usare l'output standard.

La documentazione del kernel Linux dice che tutti i sistemi dovrebbero averlo.

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

Non sono riuscito, tuttavia, a trovare i collegamenti simbolici creati nel kernel (fornita dalla distribuzione?).


1

/ dev / {stdout, stdin, stderr} funzionano in Bash su queste piattaforme:

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     root@amd64-builder.daemonology.net:/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

Ma fallisce in csh su questi:

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

6
Qual è stato il tuo caso di test? bashè speciale in quanto può essere compilato per gestire /dev/fd/xda solo i reindirizzamenti su sistemi che non hanno/dev/fd
Stéphane Chazelas

@ StéphaneChazelas Ho annullato il voto solo perché posso vedere che questo è fuorviante senza quel chiarimento (senza offesa per Ole).
Evan Carroll,

0

Un problema con /dev/stdoute amici è che potresti non avere il permesso di scrivere loro in determinate circostanze. Ad esempio, ho riscontrato questo quando invoco script da Nix e immagino strumenti simili che eseguono script in jail / sandbox / container / VM / etc. potrebbe riscontrare problemi simili.

Usando la sintassi come 1>&2funzionava in questi casi e, poiché sapevo che avrei funzionato in Bash, avrei potuto usare la sostituzione di processo per i comandi che prevedono nomi di file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.