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

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

有時我需要指定標準 IO 流之一的「等效路徑」(stdinstdoutstderr)。由於 99% 的時間我都使用 Linux,所以我只是在前面加上/dev/get/dev/stdin等,而這個“似乎做正確的事」。但是,一方面,我一直對這樣的理由感到不安(當然,因為“它似乎有效”,直到它不起作用)。此外,我對這個動作有多便攜。

所以我有幾個問題:

  1. 在 Linux 環境中,將stdin, stdout, 和stderr/dev/stdin, /dev/stdout, and 等同起來是否安全(是/否) /dev/stderr

  2. 更一般地說,這種等價是否“充分”便攜的「?

我找不到任何 POSIX 參考資料。

答案1

它早在 Linux 上就已經存在了。這是不是POSIX,儘管許多實際的 shell(包括 AT&Tkshbash)會模擬它(如果作業系統中不存在);請注意,此模擬僅適用於 shell 等級(即重定向或命令列參數,而不是作為 例如 的明確參數open())。也就是說,它應該可以在最多商業 Unix 系統,以一種或另一種方式(有時它被拼寫/dev/fd/N為各種整數N,但大多數系統都會像 Linux 和 *BSD 那樣提供符號連結)。

答案2

這些/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 的開啟檔案描述符。絕對沒有比這更重要的了。

答案3

/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     [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

但在 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

答案4

與朋友之間的一個問題/dev/stdout是,在某些情況下您可能無權寫信給他們。例如,我在呼叫腳本時遇到過這種情況尼克,我想像類似的工具可以在監獄/沙箱/容器/虛擬機/等中運行腳本。可能會遇到類似的問題。

在這些情況下使用類似的語法1>&2,因為我知道我將在 Bash 中運行,所以我可以使用流程替代對於需要檔案名稱的命令。

相關內容