/dev/stdin、/dev/stdout、および/dev/stderrの移植性はどのくらいですか?

/dev/stdin、/dev/stdout、および/dev/stderrの移植性はどのくらいですか?

場合によっては、標準IOストリームの1つの「等価パス」(stdin、、、stdout)を指定する必要があります。stderr私は99%の時間Linuxを使用しているので/dev/待つ準備ができています/dev/stdin。そしてこれ〜らしい正しいことをしなさい。

だからいくつかの質問があります。

  1. Linux環境ではstdin、、、 stdoutおよびを、およびstderrと同一視するのは安全ですか(はい/いいえ)?/dev/stdin/dev/stdout/dev/stderr

  2. より一般的に、この同等性は「十分」ですか?持ち運べる「?

POSIX 参照が見つかりません。

答え1

Linuxでは長い間使用されてきました。これはいいえPOSIX、たとえ多くの実際のシェル(AT&TkshおよびAT&Tを含むbash)がOSにない場合は、これをエミュレートしますが、このエミュレーションはシェルレベルでのみ機能します(つまり、パラメータなどの明示的に機能しないリダイレクトまたはコマンドライン引数open())。つまり、次のことが可能でなければなりません。最大何らかの方法で商用Unixシステム(時には/dev/fd/Nさまざまな整数で表記されますが、NほとんどのシステムはLinuxや* BSDなどのシンボリックリンクを提供します)。

答え2

これらの/dev/std{in,out,err}ファイルは通常、/proc/self/fd/{0,1,2}それぞれシンボリックリンクです。したがって、POSIX 定義メソッドを使用しても利点はありません。

POSIX仕様に準拠したい場合、最良の方法は出力リダイレクトを使用することです。シェル出力リダイレクトは、以下で定義されます。POSIX規格。また、STDIN、STDOUT、およびSTDERRファイル記述子番号もあります。POSIX
簡単に言えば、このようなことは>&2確かにうまくいくでしょう。

しかし、注目すべき1つの重要な点は、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

1つの問題/dev/stdoutは、場合によっては手紙を書く権限がない可能性があることです。たとえば、スクリプトを呼び出すときにこの状況が発生しました。ニックス、刑務所/サンドボックス/コンテナ/VM/などでスクリプトを実行する同様のツールを想像します。同様の問題が発生する可能性があります。

のような構文を使用すると、1>&2Bashで実行されることがわかっているので、次のように使用できます。プロセスの交換ファイル名が必要なコマンドの場合。

関連情報