web-dev-qa-db-ja.com

/ dev / stdin、/ dev / stdout、/ dev / stderrはどの程度移植性がありますか?

標準のIOストリーム(stdinstdoutstderr)の「パス相当」を指定する必要がある場合があります。 Linuxで作業する時間の99%から、/dev/を付加して/dev/stdinなどを取得し、これを "seemsで正しく実行する"ようにしています。しかし、 1つには、そのような根拠についてはいつも不安でした(もちろん、うまくいかないまでは「うまくいくように見える」からです)さらに、この操作がどれほどポータブルであるかについては、あまり意味がありません。

だから私はいくつかの質問があります:

  1. Linuxのコンテキストでは、stdinstdout、およびstderr/dev/stdin/dev/stdoutと同等にしても安全ですか(はい/いいえ)。および/dev/stderr

  2. より一般的には、この同等性は「適切にportable "ですか?

POSIXリファレンスが見つかりませんでした。

60
kjo

Linuxでその先史時代に戻ってきました。 not POSIXですが、多くの実際のシェル(AT&T kshおよびbashを含む)は、OSに存在しない場合にそれをシミュレートします。このシミュレーションはシェルレベルでのみ機能することに注意してください(つまり、リダイレクトやコマンドラインパラメーターであり、open()などの明示的な引数ではありません)。とは言っても、何らかの方法でmost商用Unixシステムで使用できるはずです(時には/dev/fd/Nはさまざまな整数Nですが、それを備えたほとんどのシステムは、Linuxおよび* BSDと同様にシンボリックリンクを提供します。

38
geekosaur

/dev/std{in,out,err}ファイルは通常、(それぞれ)/proc/self/fd/{0,1,2}へのシンボリックリンクです。そのため、POSIXで定義されているメソッドを使用しても、何も得られません。

POSIX準拠にしたい場合、これを行う最善の方法は、出力リダイレクトを使用することです。シェル出力リダイレクトは POSIX標準 で定義されています。さらに、STDIN、STDOUT、STDERRファイル記述子番号も [〜#〜] posix [〜#〜] の一部です。
要するに、>&2のようなものが動作することが保証されています。

ただし、STDIN、STDOUT、およびSTDERRの使用法は、プログラムの開始方法に主観的であることに注意してください。ファイル記述子1がファイルへのオープンハンドルとしてプログラムが開始された場合、プログラムはそれを受け入れる必要があります。プログラムに/dev/stdoutを開かせたとしても、ファイル記述子1を開くだけで、そのファイルを指し示すことができます。
これが回避しようとしているものである場合は、TTYを直接開く必要があります。通常、リダイレクトを行わない場合、STDIN、STDOUT、およびSTDERRはすべて、同じTTYを指すオープンファイル記述子です。それ以上のことは絶対にありません。

22
Patrick

POSIX 7では、これらは拡張機能であると述べています。

基本定義 、セクション2.1.1要件:

システムは非標準の拡張機能を提供する場合があります。これらはPOSIX.1-2008で必要とされない機能であり、以下が含まれますが、これらに限定されません。

[...]

  • 特別なプロパティを持つ追加のキャラクタースペシャルファイル(たとえば、/dev/stdin/dev/stdout、と/dev/stderr

POSIX HTMLをgreppingすることで見つかります: POSIX C API関数のリストはどこですか?

また、奇妙なことに、uuencodeツール /dev/stdoutに魔法の効果を与える

/dev/stdoutdecode_pathnameオペランドを指定すると、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

ただし、これらのシンボリックリンクがカーネルで作成されている場所を見つけることができませんでした(ディストリビューションが提供されていますか?)。

/ 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
3
Ole Tange

/dev/stdoutとその友達の問題の1つは、特定の状況ではそれらに書き込む権限がない場合があることです。たとえば、私は Nix からスクリプトを呼び出すときにこれに遭遇しました。jails/ sandboxes/containers/VMs/etcでスクリプトを実行する同様のツールを想像します。同様の問題が発生する可能性があります。

1>&2のような構文を使用すると、これらのケースで機能し、Bashで実行することを知っていたので、ファイル名を期待するコマンドに プロセス置換 を使用できました。

0
Warbo