昨日、シェルでそれを言うこのSOコメントを読みました(少なくともbash
)>&-
「と同じ結果になります」>/dev/null
。
そのコメントは、実際にはその情報源としてABSガイドを参照しています。しかし、その情報源によると、>&-
構文は「ファイル記述子を閉じる」。
ファイル記述子を閉じてnullデバイスにリダイレクトする2つのアクションが完全に同等であるかどうかは私にはわかりません。だから私の質問は:彼らですか?
表面的には、記述子を閉じることはドアを閉じることに似ているように見えますが、それをnullデバイスにリダイレクトすると、リンボへの扉が開かれます。閉じたドアを見ると何も投げ出そうとしないので、この2つはまったく同じではないように見えますが、開いたドアを見るとできると思います。
言い換えれば、私はいつも>/dev/null
かどうか疑問に思っていました cat mybigfile >/dev/null
を意味します 実際にはファイルのすべてのバイトを処理し、それを/dev/null
に書き込みます。 それを忘れます。一方、シェルが閉じたファイル記述子に遭遇した場合、cat
かどうかという疑問は残りますが、シェルは単に何も書き込まないだろうと思う傾向があります(ただし、確かではありません)。 引き続き読む すべてのバイト。
このコメントには>&-
と書かれています および>/dev/null
「すべき 」は同じですが、それは私にとってそれほどはっきりとした答えではありません。標準コアまたはソースコアを参照しているかどうかにかかわらず、より信頼できる回答が欲しいのですが…
承認された回答:
いいえ、あなたは確かにしない ファイル記述子0、1、および2を閉じたい。
そうすると、アプリケーションが最初にファイルを開くときに、ファイルはstdin / stdout/stderrになります…
たとえば、次の場合:
echo text | tee file >&-
tee
の場合 (少なくともbusyboxのようないくつかの実装)は書き込み用にファイルを開き、ファイル記述子1(stdout)で開きます。つまり、tee
text
を書き込みます file
に2回 :
$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "textn", 8193) = 5
write(1, "textn", 5) = 5
write(1, "textn", 5) = 5
read(0, "", 8193) = 0
exit_group(0) = ?
これはセキュリティの脆弱性を引き起こすことが知られています。例:
chsh 2>&-
そしてchsh
(setuidアプリケーション)/etc/passwd
にエラーメッセージを書き込んでしまう可能性があります 。
一部のツールや一部のライブラリでさえ、それを防ごうとします。たとえば、GNU tee
書き込み用に開いたファイルに0、1、2が割り当てられている場合、busybox tee
の場合、ファイル記述子は2より上の1つに移動します。 しません。
ほとんどのツールは、stdoutに書き込めない場合(たとえば、開いていないため)、stderrにエラーメッセージを報告します(ユーザーの言語で、ローカリゼーションファイルを開いて解析するための追加の処理を意味します...)。効率が大幅に低下し、プログラムが失敗する可能性があります。
いずれにせよ、それはより効率的ではありません。プログラムは引き続きwrite()
を実行します システムコール。 write()
が最初に失敗した後、プログラムがstdout / stderrへの書き込みをあきらめた場合にのみ、より効率的になります。 システムコールですが、プログラムは通常それを行いません。通常、エラーで終了するか、試行を続けます。