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

kjo*_*kjo 69 io file-descriptors posix portability

有时,我需要指定标准 IO 流 ( stdin, stdout, stderr)之一的“等效路径” 。因为我 99% 的时间都在使用 Linux,所以我只是/dev/在准备 get/dev/stdin等,而这“似乎做对了”。但是,一方面,我一直对这样的理由感到不安(因为,当然,“它似乎有效”,直到它没有为止)。此外,我对这种操作的便携性没有很好的了解。

所以我有几个问题:

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

  2. 更一般地说,这个等价物是否“足够便携”?

我找不到任何 POSIX 参考。

gee*_*aur 42

它已经可以在 Linux 上使用,回到它的史前时代。它不是POSIX,尽管许多实际的 shell(包括 AT&Tkshbash)会模拟它,如果它不存在于操作系统中;请注意,此模拟仅适用于 shell 级别(即重定向或命令行参数,而不是作为 eg 的显式参数open())。也就是说,它应该可以在大多数商业 Unix 系统上以一种或另一种方式使用(有时它被拼写/dev/fd/N为各种整数N,但大多数系统会像 Linux 和 *BSD 那样提供符号链接)。

  • 事实上,`/dev/std{in,out,err}` 被明确列为不属于 [POSIX.1-2008](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html ) 标准。 (14认同)
  • 似乎`ash`在initrd中不支持`/dev/stdout`(http://git.razvi.ro/?p=openwrt.org%2Fopenwrt.git&a=commit&h=c20510da95c90df8cb4581c7bbc85d6eb9dc218f) (2认同)
  • 到 2021 年,在“P1003.1™-202x,草案 2.1,2021 年 8 月”(当前的 POSIX 草案)中仍然**明确列为不属于 POSIX**。 (2认同)

phe*_*mer 24

这些/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 的打开文件描述符。绝对没有比这更多的了。

  • 你能澄清一下 `/proc/self/fd/1` 还是 `/dev/fd/1` 是 POSIX 的一部分吗? (7认同)
  • +1,尤其是“一件重要的事情”部分;我将分部分消化这个:) (3认同)

Cir*_*郝海东 5

POSIX 7 说它们是扩展。

基本定义,第 2.1.1 节要求:

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

[...]

  • 具有特殊属性的附加字符特殊文件(例如,? /dev/stdin、? /dev/stdout、? 和? /dev/stderr

通过 grepping POSIX HTML 找到:POSIX C API 函数列表在哪里?

同样很奇怪的是,该uuencode工具提供/dev/stdout了一种神奇的效果

指定decode_pathname操作数/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
Run Code Online (Sandbox Code Playgroud)

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


Ole*_*nge 5

/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
Run Code Online (Sandbox Code Playgroud)

但是在 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
Run Code Online (Sandbox Code Playgroud)

  • 你的测试用例是什么?`bash` 很特别,因为它可以被编译为自己处理 `/dev/fd/x`,以便在没有 `/dev/fd` 的系统上进行重定向 (9认同)