/ dev / stdin,/ dev / stdout和/ dev / stderr的可移植性如何?


55

偶尔我需要指定一个“路径相当于”标准的IO流之一(的stdinstdoutstderr)。由于我有99%的时间使用Linux,所以我只是假装/dev/get /dev/stdin等,这“ 似乎做对了”。但是,一方面,我一直对这样的理由感到不安(因为“当然,它似乎起作用”,直到不起作用为止)。此外,我对这种机动的便携性没有很好的认识。

所以我有几个问题:

  1. 在Linux中的情况下,它是安全(是/否)划上等号stdinstdout以及stderr/dev/stdin/dev/stdout/dev/stderr

  2. 更笼统地说,这种等效性“足够便携 ”吗?

我找不到任何POSIX参考。



Answers:


36

早在Linux上就可以使用它了。它不是 POSIX,但是如果OS中不存在许多实际的shell(包括AT&T kshbash),它将进行模拟。请注意,此模拟仅在外壳程序级别有效(即重定向或命令行参数,而不作为eg的显式参数open())。就是说,它应该在大多数商业Unix系统上以一种或另一种方式可用(有时它是/dev/fd/N为各种整数拼写的N,但是大多数系统都将像Linux和* BSD一样提供符号链接)。


13
实际上,/dev/std{in,out,err}被明确列为不属于POSIX.1-2008标准的一部分。
jw013

看来,ash不支持/dev/stdoutinitrd文件中(git.razvi.ro/...
CMCDragonkai

@CMCDragonkai:那不是可由shell处理的/ dev / stdout,您对initrd有什么期望?为了使它尽可能小,它缺少大多数功能。
约书亚

22

这些/dev/std{in,out,err}文件通常只是/proc/self/fd/{0,1,2}分别的符号链接。因此,使用POSIX定义的方法没有任何收获。

如果要符合POSIX,最好的方法是使用输出重定向。Shell输出重定向在POSIX标准中定义。此外,STDIN,STDOUT,STDERR文件描述符号也是POSIX的一部分。
简而言之,类似>&2的东西一定能起作用。

但是要注意的重要一件事是STDIN,STDOUT和STDERR的使用取决于程序的启动方式。如果程序以文件描述符1作为文件的打开句柄启动,则您的程序只需接受它。即使您要打开程序/dev/stdout,它所要做的就是打开文件描述符1,该描述符仍将指向该文件。
如果这是您要解决的问题,则需要直接打开TTY。通常,无需进行任何重定向,STDIN,STDOUT和STDERR都只是指向同一TTY的打开文件描述符。绝对没有什么比这更多的了。


2
+1,特别是对于“一件重要的事情”部分;我将分部分介绍这个问题:)
Alois Mahdal 2012年

4
你能澄清,如果/proc/self/fd/1还是/dev/fd/1有POSIX的一部分?
Steven Penny

/dev/std???只是/proc/self/fd在Linux上的符号链接。
斯特凡Chazelas

5

POSIX 7表示它们是扩展。

基本定义,第2.1.1节要求:

系统可能提供非标准扩展。这些是POSIX.1-2008不需要的功能,可能包括但不限于:

[...]

  • 具有特殊性质的其他字符特殊文件(例如,  /dev/stdin,  /dev/stdout,和  /dev/stderr

通过对POSIX HTML进行grep发现:POSIX C API函数的列表在哪里?

也相当古怪,该uuencode工具提供了/dev/stdout一个神奇的效果

指定的解码器路径名操作数/dev/stdout 将指示uudecode将使用标准输出。

Linux内核文档说所有系统都应该拥有它。

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

但是,我找不到在内核中创建这些符号链接的位置(是否提供了发行版?)。


1

/ dev / {stdout,stdin,stderr}在以下平台上的Bash中工作:

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

但是在csh上失败了:

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
你的测试用例是什么?bash特别是因为它可以被编译处理/dev/fd/x本身对重定向上没有这样的系统/dev/fd
斯特凡Chazelas

@StéphaneChazelas我之所以投票,是因为我没有经过澄清就可以看出这是误导性的(对Ole没有冒犯性)。
埃文·卡罗尔

0

/dev/stdout和朋友的一个问题是,在某些情况下,您可能没有写信给他们的权限。例如,当我从Nix调用脚本时遇到了这个问题,并且我想象有类似的工具可以在jails / sandboxes / containers / VMs / etc中运行脚本。可能会遇到类似的问题。

1>&2在这种情况下使用类似的语法,并且因为我知道我将在Bash中运行,所以我可以将进程替换用于需要文件名的命令。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.