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

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

昨日私は読んだこのコメントこれはシェルで(少なくともbash>&-「と同じ結果があることを意味します」>/dev/null

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

ファイル記述子を閉じるのと空のデバイスにリダイレクトするのがまったく同じかどうかはわかりません。だから私の質問は:そうですか?

表面的に記述子を閉じるのはドアを閉じるのと同じですが、それを空のデバイスにリダイレクトするのは地獄のドアを開くのと同じです!私にとって、その2つはまったく同じではないようです。なぜなら、閉じたドアが見えれば何も投げないようにしようとしますが、開いたドアが見えれば投げることができると思うからです。

つまり、>/dev/nullこれがcat mybigfile >/dev/null実際にファイルのすべてのバイトを処理し、/dev/null忘れた場所に書き込むことを意味するのだろうか?一方、シェルが閉じたファイル記述子に出会うと、何も書かないと思う傾向があります(わかりませんが)。それでもcat書くかどうか疑問は残っています。読むバイトあたり。

このコメント>&-と言う>/dev/nullしなければならない「同じですが、私はそれに触れる答えではありません。

答え1

いいえ、もちろんです。いいえファイル記述子0、1、2を閉じたいです。

これにより、アプリケーションが初めてファイルを開くと、ファイルはstdin / stdout / stderr ...になります。

たとえば、次のような場合:

echo text | tee file >&-

(少なくともbusybox 'などのいくつかの実装では)書き込み用にファイルを開くと、teeファイル記述子1(stdout)で開きます。したがって、2回tee作成されます。textfile

$ 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

一部のツールと一部のライブラリは、このようなことが発生しないようにします。たとえば、teeGNUが書き込み用に開いたファイルに0、1、2が割り当てられている場合、GNUはファイル記述子を2位に移動しますが、busyboxはteeそうではありません。

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

決してより効率的ではありません。プログラムは依然としてwrite()システムコールを実行します。プログラムが最初のシステム呼び出しに失敗した後にstdout / stderrへの書き込みを放棄した場合にのみ効率的ですが、プログラムは通常write()これを行いません。通常、エラーが発生し、終了または継続しようとします。

答え2

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

これはあなたの質問に対する完全な答えではありませんが、そうです。上記は動作方法です。

cat指定されたファイルを読み取り、ファイルが指定されていない場合は標準入力と出力を読み取ります。標準出力へ最後に名前付きファイル(標準入力を含む)でEOFが見つかるまでの内容。それはそれ働く

追加すると、>/dev/null標準出力を/ dev / nullにリダイレクトできます。これは、記録されたすべての内容を削除して読み取るとすぐにEOFを返す特別なファイル(デバイスノード)です。 I / Oリダイレクトは、個々のアプリケーションではなくシェルが提供する機能であり、I / Oリダイレクトには特別なものはありません。名前/dev/null、ほとんどの場合にのみ発生します。Unixシリーズシステム

デバイスノードの正確なメカニズムはオペレーティングシステムによって異なりますが、cat(GNUシステムのcoreutilsを表す)はクロスプラットフォームです(実行には同じソースコードが必要です)。少なくともLinuxとHurd)したがって、特定のオペレーティングシステムのカーネルに依存することはできません。また、別の名前で/ dev / nullエイリアスを生成する場合(Linuxでは、同じ州/マイナー番号を持つデバイスノードを意味します)、まだ機能します。そして、他の場所(例:/ dev / zero)に記録しても、動作が実際に同じ場合が常にあります。

したがって、cat/ dev / nullの特別な属性については知らず、実際にリダイレクトについても最初は知りません。それでも同じことをする必要があります。指定したファイルを読み込み、そのファイルの内容を標準出力に出力します。標準出力がcat穴に入るのはcatそれ自体の問題ではありません。

関連情報