>&-は> / dev / nullよりも効率的ですか?


58

昨日、私はこのSOコメントを読みました。このコメントでは、シェル内で(少なくともbash)は>&-「と同じ結果になります」と述べてい>/dev/nullます。

そのコメントは、実際にはその情報源としてABSガイドを参照しいます。しかし、そのソースは、>&-構文が「ファイル記述子を閉じる」と述べています。

ファイル記述子を閉じてヌルデバイスにリダイレクトするという2つのアクションが完全に同等であるかどうかは明確ではありません。だから私の質問は:彼らですか?

表面的には、記述子を閉じることはドアを閉じることに似ていますが、ヌルデバイスにリダイレクトすることはリンボへのドアを開くことです!閉じたドアが見えても、そこから何も捨てようとしないので、この2つはまったく同じようには見えませんが、開いたドアがあれば、できると思います。

言い換えれば、ファイルのすべてのバイトを実際に処理し、それを忘れたファイルに書き込むことを>/dev/null意味するのかどうか、私はいつも疑問に思っていました。一方、シェルが閉じられたファイル記述子に遭遇した場合、私は考える傾向がある(ただし、わからない)疑問が残るかどうかかかわらず、それは単に、何も書かないということはまだだろう読んですべてのバイトを。cat mybigfile >/dev/null/dev/nullcat

このコメントは「同じである必要>&-あります>/dev/null」と言っていますが、それは私にとってそれほど圧倒的な答えではありません。標準またはソースコアを参照するかどうかに関係なく、より信頼できる回答を希望します。


私が慈善活動をしたいのであれば、コメントはそれらが同じ方法で実装されたことを意味するものではなく、どちらもあなたがプログラムの出力を見ることを妨げるという同じ最終結果を持っているということです。
バーマー14年

回答:


71

いいえ、ファイル記述子0、1、2を閉じたくないのは確かです

そうすると、アプリケーションが初めてファイルを開いたときに、stdin / stdout / stderrになります...

たとえば、次の場合:

echo text | tee file >&-

ときtee(busyboxのような、少なくともいくつかの実装は、 ')書き込み用のファイルを開くには、ファイルディスクリプタ1(標準出力)に公開されます。次のteeようにtext2回書き込みますfile

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "text\n", 8193)                 = 5
write(1, "text\n", 5)                   = 5
write(1, "text\n", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

これはセキュリティの脆弱性を引き起こすことが知られています。例えば:

chsh 2>&-

また、chsh(setuidアプリケーション)でエラーメッセージを書き込むことがあります/etc/passwd

いくつかのツールといくつかのライブラリでさえ、それを防ぐようにしています。例えば、GNU teeは、書き込みのために開くファイルに0、1、2が割り当てられ、busyboxには割り当てられない場合、ファイル記述子を2つ以上に移動しますtee

ほとんどのツールは、stdoutに書き込めない場合(たとえば、開いていないため)、stderrにエラーメッセージを報告します(ユーザーの言語で、ローカライズファイルを開いて解析するための追加処理を意味します...)。効率が大幅に低下し、プログラムが失敗する可能性があります。

いずれにせよ、それはより効率的ではありません。プログラムは引き続きwrite()システムコールを実行します。プログラムが最初に失敗したwrite()システムコールの後にstdout / stderrへの書き込みを放棄した場合にのみ、より効率的になりますが、プログラムは一般にそうしません。通常、エラーで終了するか、試行を続けます。


4
最後の段落が一番上にある場合(OPの質問に最も直接答えるものであるため)、この答えはさらに良いと思います。そして、それがほとんどうまくいったとしてもなぜそれが悪い考えであるのかについて議論し続けました。しかし、私はそれを取る、賛成票を持っています。;)
CVn 14年

@StéphaneChazelas:マイケルが言ったように、最後のパラグラフが一番上にあると思っていましたが、それを明確にしてくれてありがとう、実際にはおそらく問題を引き起こすだけです。だから、補助的な質問は、FDを閉じることが実際にいつ役立つのでしょうか?または、別の質問としてそれを尋ねるべきですか?
jamadagni 14年


1
@jamadagniStéphaneによって提供されたリンクが質問に答えない場合、2つの方法の相対的な効率に直接関係しないため、別の質問の始まりのように聞こえます。
CVn

1
Stephaneがこの非常に重要なセキュリティ警告で始まることを感謝します。最後の段落が一番上にある場合、それは目立たなくなります。私から+1。
オリビエデュラック14年

14

IOW は、ファイルのすべてのバイトを実際に処理し、それを忘れて書き込むことを>/dev/null意味するのかどうか、いつも疑問に思っていました。cat mybigfile >/dev/null/dev/null

それはあなたの質問に対する完全な答えではありませんが、はい、上記はそれがどのように機能するかです。

cat指定されたファイル、またはファイルが指定されていない場合は標準入力を読み取り、最後に指定されたファイル(標準入力を含む)でEOFが発生するまでそれらの内容を標準出力に出力します。つまりその仕事。

追加>/dev/nullすると、標準出力が/ dev / nullにリダイレクトされます。それは特別なファイル(デバイスノード)で、そこに書き込まれたものをすべて捨てます(そして読み取り時にすぐにEOFを返します)。I / Oリダイレクトは、個々のアプリケーションではなく、シェルによって提供される機能であり、/ dev / null という名前には魔法のようなものはなく、ほとんどのUnixライクなシステムに存在するものだけです

デバイスノードの特定のメカニズムはオペレーティングシステムごとに異なりますが、cat(GNUシステムではcoreutilsを意味する)はクロスプラットフォームであることに注意することも重要です(少なくとも LinuxとHurd)したがって、特定のオペレーティングシステムカーネルへの依存関係を取ることはできません。さらに、別の名前で/ dev / nullエイリアス(Linuxでは、これは同じメジャー/マイナーデバイス番号を持つデバイスノードを意味します)を作成した場合でも機能します。そして、同じように効果的に動作する別の場所(/ dev / zeroなど)に書き込む場合が常にあります。

したがってcat、/ dev / nullの特別なプロパティは認識されず、そもそもリダイレクトは認識されない可能性がありますが、それでもまったく同じ作業を実行する必要があります。指定されたファイルを読み取り、これらのファイルを標準出力に追加します。の標準出力がcatたまたまボイドになることは、それcat自体が懸念することではありません。


2
あなたの答えを拡張するには:はい、cat mybigfile > /dev/null原因となりますcatのすべてのバイトを読み取るためにbigfileメモリに。そして、すべてのnバイトに対して、を呼び出しますwrite(1, buffer, n)catプログラムには知られていないが、write意志は絶対に何もしません(たぶん些細な簿記を除いて)。への書き込みで/dev/nullは、すべてのバイトを処理する必要はありません。
Gマンは「Reinstate Monica」

2
/ dev / nullデバイスのLinuxカーネルソースを読んだとき、私は感動しました。free()ingバッファーなどの精巧なシステムがあることを期待していましたが、基本的にはreturn()にすぎません。
ブライアンミントン14年

4
@ G-Man:すべての場合にそれが真実であることを保証できるとは知らない。私は今、証拠を見つけることができませんが、私はどちらかのいくつかの実装を思い出すcatか、cpそれがで働くだろうmmap呼び出し、その後、メモリにソースファイルの大きな塊をINGのwrite()マッピングされた領域の上に。に書き込みを行っていた/dev/null場合、write()呼び出しはソースファイルのページに障害を起こすことなくすぐに返されるため、実際にディスクから読み取られることはありません。
ネイト・エルドリッジ14年

2
また、GNUのようなものcatは多くのプラットフォームで実行されますが、ソースコードをざっと見ると多くの#ifdefs が表示されます。すべてのプラットフォームで実行される文字通りのコードではなく、システムに依存するセクションがたくさんあります。
ネイト・エルドレッジ14年

@NateEldredge:興味深い点ですが、私はマイケルの答えに基づいていたので、マイケルと矛盾するほどあなたは私と矛盾していません。
G-Manは「
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.