GNU/Linux >> Linux の 問題 >  >> Linux

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

昨日、シェルでそれを言うこの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つに移動します。 しません。

関連:Linux – `hostname`のデフォルトファイルは何ですか?

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

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


Linux
  1. Linux:/ dev / console、/ dev / tty、/ dev / tty0の違いは?

  2. Linux の /dev/zero および /dev/null ファイルとは

  3. 別のshファイルからshファイルを実行する方法

  1. /dev/sdb:そのようなファイルやディレクトリはありません (ただし /dev/sdb1 などは存在します)

  2. Linux:/dev/console 、 /dev/tty 、 /dev/tty0 の違い

  3. Linux が /dev/tty と /dev/tty0 を使用する方法

  1. Linuxは複数の連続したパスセパレーター(/ home //// username /// file)をどのように処理しますか?

  2. echo または print /dev/stdin /dev/stdout /dev/stderr

  3. /dev/tcp を使用するために < または > が必要な理由