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


55

時折、私は標準IOストリームの1つ(の「等価パス」を指定する必要がありstdinstdoutstderr)。私は、Linuxで動作する時間の99%以来、私は先頭に追加/dev/取得する/dev/stdinなど、これが「思わ正しいことを行うために」。しかし、1つには、そのような理論的根拠について私はいつも不安でした(もちろん、うまくいかないまで「うまくいくようだから」)。さらに、私はこの操作がどれほどポータブルであるかについて良い感覚を持っていません。

そこで、いくつか質問があります。

  1. Linuxののコンテキストでは、それが安全である(はい/いいえ)と同一視するstdinstdoutstderrして/dev/stdin/dev/stdout/dev/stderr

  2. より一般的には、この同等性は「十分に移植可能」ですか?

POSIXの参照が見つかりませんでした。



回答:


36

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


13
実際、POSIX.1-2008標準の/dev/std{in,out,err}一部ではないものとして具体的にリストされています。
jw013

initrd(git.razvi.ro/…ashではサポートさ/dev/stdoutれていないようです
-CMCDragonkai

@CMCDragonkai:それはシェルで処理できる/ dev / stdoutではなく、initrdに何を期待していましたか?実用的にできるだけ小さくするために、ほとんどの機能が欠けています。
ジョシュア

22

/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を開くだけで、ファイル記述子1がそのファイルを指すようになります。
これが回避しようとしているものである場合は、TTYを直接開く必要があります。通常、リダイレクションが行われない場合、STDIN、STDOUT、およびSTDERRはすべて、同じTTYを指すオープンファイル記述子です。それ以上のものは絶対にありません。


2
+1、特に「1つの重要なこと」の部分。私はこれを部分的に消化するつもりです:)
アロイス・マーダル

4
POSIXの一部かどう/proc/self/fd/1かを明確にできます/dev/fd/1か?
スティーブンペニー14年

/dev/std???/proc/self/fdLinux上のシンボリックリンクのみです。
ステファンシャゼラス

5

POSIX 7は、それらが拡張機能であると言います。

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

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

[...]

  • 特殊な性質を持つ追加の文字特殊ファイル(例えば、  /dev/stdin、  /dev/stdout、及び  /dev/stderr

POSIX HTMLをgrepして見つけた: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

ただし、これらのシンボリックリンクがカーネルのどこに作成されているかはわかりません(ディストリビューションは提供されますか?)。


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明確化せずにこれが誤解を招くのを見ることができるからといって、私はダウン票を投じました(オレに対する攻撃はありません)。
エヴァンキャロル

0

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.