Wie portabel sind / dev / stdin, / dev / stdout und / dev / stderr?


55

Gelegentlich muss ich einen „Pfad-Äquivalent“ von einem der Standard - IO - Streams , um anzugeben ( stdin, stdout, stderr). Da 99% der Zeit , die ich mit Linux arbeiten, ich voranstellen , nur /dev/zu bekommen /dev/stdin, usw., und diese „ scheint das Richtige zu tun“. Aber zum einen war ich mir über eine solche Begründung immer unwohl (weil "es anscheinend funktioniert", bis es nicht funktioniert). Außerdem habe ich keinen guten Sinn dafür, wie tragbar dieses Manöver ist.

Ich habe also ein paar Fragen:

  1. Im Rahmen von Linux, ist es sicher (ja / nein) zu stdin, stdoutund stderrmit /dev/stdin, /dev/stdoutund /dev/stderr?

  2. Ist diese Äquivalenz im Allgemeinen "angemessen tragbar "?

Ich konnte keine POSIX-Referenzen finden.



Antworten:


36

Es war unter Linux schon in der Vorgeschichte verfügbar. Es ist kein POSIX, obwohl es von vielen tatsächlichen Shells (einschließlich AT & T kshund bash) simuliert wird, wenn es im Betriebssystem nicht vorhanden ist. Beachten Sie, dass diese Simulation nur auf der Shell-Ebene funktioniert (dh Umleitung oder Befehlszeilenparameter, nicht als explizites Argument für z open(). B. ). Das heißt, es sollte auf den meisten kommerziellen Unix-Systemen auf die eine oder andere Weise verfügbar sein (manchmal wird es /dev/fd/Nfür verschiedene Ganzzahlen geschrieben N, aber die meisten Systeme mit solchen Symbolen bieten Symlinks wie Linux und * BSD).


13
Tatsächlich /dev/std{in,out,err}sind sie ausdrücklich nicht als Teil des POSIX.1-2008- Standards aufgeführt.
JW013

Es scheint, dass in initrd ( git.razvi.ro/… ) ashnicht unterstützt/dev/stdout
CMCDragonkai

@CMCDragonkai: Das ist kein / dev / stdout, das von der Shell verarbeitet werden kann, und was haben Sie von initrd erwartet? Es fehlen die meisten Schönheiten, um es so klein wie möglich zu machen.
Joshua

22

Die /dev/std{in,out,err}Dateien sind normalerweise nur Symlinks zu /proc/self/fd/{0,1,2}(bzw.). Als solche gibt es nichts, was über die Verwendung von Methoden, die POSIX-definiert sind, gewonnen wurde.

Wenn Sie POSIX-konform sein möchten, verwenden Sie am besten die Ausgabeumleitung. Die Shell-Ausgabeumleitung ist im POSIX-Standard definiert . Zusätzlich sind die Dateideskriptornummern STDIN, STDOUT und STDERR Bestandteil von POSIX .
Kurz gesagt, Dinge wie >&2funktionieren garantiert.

Wichtig ist jedoch, dass die Verwendung von STDIN, STDOUT und STDERR sich subjektiv auf den Programmstart auswirkt. Wenn das Programm mit Dateideskriptor 1 als offenem Handle für eine Datei gestartet wurde, muss es von Ihrem Programm nur akzeptiert werden. Selbst wenn Sie das Programm öffnen würden /dev/stdout, würde es nur den Dateideskriptor 1 öffnen, der immer noch auf diese Datei verweist.
Wenn Sie dies versuchen, müssen Sie das TTY direkt öffnen. Normalerweise sind STDIN, STDOUT und STDERR ohne Umleitung nur offene Dateideskriptoren, die auf dasselbe TTY verweisen. Es gibt absolut nichts mehr als das.


2
+1, insbesondere für den Teil "eine wichtige Sache"; Ich werde das in Teilen verdauen :)
Alois Mahdal

4
Können Sie klären, ob /proc/self/fd/1oder ob Sie /dev/fd/1Teil von POSIX sind?
Steven Penny

/dev/std???sind nur symlinks zu /proc/self/fdunter Linux.
Stéphane Chazelas

5

POSIX 7 gibt an, dass es sich um Erweiterungen handelt.

Basisdefinitionen , Abschnitt 2.1.1 Anforderungen:

Das System bietet möglicherweise nicht standardmäßige Erweiterungen. Diese Funktionen werden von POSIX.1-2008 nicht benötigt und können unter anderem Folgendes umfassen:

[...]

  • Zusätzliche Zeichenspezialdateien mit speziellen Eigenschaften (z. B  /dev/stdin.  /dev/stdout,, und  /dev/stderr)

Gefunden durch Aufrufen des POSIX-HTML: Wo befindet sich die Liste der POSIX-C-API-Funktionen?

Auch ziemlich seltsam, gibt das uuencodeWerkzeug einen magischen Effekt :/dev/stdout

Das Angeben eines decode_pathname- Operanden von /dev/stdout soll angeben, dass uudecode die Standardausgabe verwenden soll.

Die Linux-Kernel-Dokumentation besagt, dass alle Systeme sie haben sollten.

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

Ich konnte jedoch nicht finden, wo diese Symlinks im Kernel erstellt werden (Distribution bereitgestellt?).


1

/ dev / {stdout, stdin, stderr} arbeiten in Bash auf diesen Plattformen:

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

Scheitert aber in csh an diesen:

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
Was war dein Testfall? bashist etwas Besonderes, da es kompiliert werden kann, um /dev/fd/xfür Umleitungen auf Systemen, die nicht über/dev/fd
Stéphane Chazelas

@ StéphaneChazelas Ich habe nur herabgestimmt, weil ich sehe, dass dies ohne diese Klarstellung irreführend ist (keine Beleidigung für Ole).
Evan Carroll

0

Ein Problem mit /dev/stdoutund mit Freunden ist, dass Sie unter bestimmten Umständen möglicherweise nicht berechtigt sind, an sie zu schreiben. Ich habe dies zum Beispiel beim Aufrufen von Skripten aus Nix festgestellt und mir ähnliche Tools vorgestellt, mit denen Skripten in Jails / Sandboxes / Containern / VMs / etc ausgeführt werden. kann auf ähnliche Probleme stoßen.

Mit Syntax wie 1>&2in diesen Fällen gearbeitet und, da ich wusste , dass ich in Bash laufen würde, könnte ich mit Prozess - Substitution für Befehle , die Dateinamen erwarten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.