昨日私は読んだこのコメントこれはシェルで(少なくとも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
作成されます。text
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
。
一部のツールと一部のライブラリは、このようなことが発生しないようにします。たとえば、tee
GNUが書き込み用に開いたファイルに0、1、2が割り当てられている場合、GNUはファイル記述子を2位に移動しますが、busyboxはtee
そうではありません。
ほとんどのツールは、標準出力に書き込めない場合(たとえば開かれていないため)、標準エラーに関するエラーメッセージを報告します(ユーザーの言語では、ローカライズされたファイルを開いて解析する追加の処理を意味します)。 ..). .)、したがって効率が大幅に減少し、プログラムが失敗する可能性があります。
決してより効率的ではありません。プログラムは依然としてwrite()
システムコールを実行します。プログラムが最初のシステム呼び出しに失敗した後にstdout / stderrへの書き込みを放棄した場合にのみ効率的ですが、プログラムは通常write()
これを行いません。通常、エラーが発生し、終了または継続しようとします。