なぜ `sort <“ $ f1”`が `sort —“ $ f1”`よりも優先され、なぜこれが `sort“ $ f1”`よりも優先されるのですか?


29

https://unix.stackexchange.com/a/458074/674から

-- 任意の引数をコマンドに渡すときに使用することを忘れないでください(または、可能な場合はリダイレクトを使用してください)。だから、sort -- "$f1"またはより良いsort < "$f1"の代わりにsort "$f1"

使用--とリダイレクトが望ましいのはなぜですか?

なぜsort < "$f1"優先されるのsort -- "$f1"ですか?

なぜ sort -- "$f1"優先されるのsort "$f1"ですか?

ありがとう。


回答:


55
sort "$f1"

値のために失敗した$f1こと開始と-した場合のか、ここsortで始まるいくつかの+(と呼ばれるファイルのための深刻な結果持つことができ-o/etc/passwd、たとえば)を。

sort -- "$f1"

-- オプションの終わりを示す)は、これらの問題のほとんどに対処しますが、呼び出されたファイルでは失敗します-sort代わりにstdinを意味すると解釈されます)。

sort < "$f1"

これらの問題はありません。

ここでは、ファイルを開くのはシェルです。また、ファイルを開けない場合、潜在的にさらに有用なエラーメッセージ(たとえば、ほとんどのシェルはスクリプト内の行番号を示します)を取得し、使用するとエラーメッセージが一貫することも意味します。可能な限りファイルをリダイレクトします。

そして

sort < "$f1" > out

(反対sort -- "$f1" > out)、"$f1"開くことができない場合、out作成/切り捨てられsortず、実行されません。

いくつかの起こりうる混乱(以下のコメントを参照)をクリアするために、ファイル自体がシーク可能である限り、コマンドmmap()がファイルを実行したり、ファイルlseek()内で実行したりすることを妨げませんsort。唯一の違いは、ファイルがシェルによって以前に開かれ、ファイル記述子0で開かれるのに対して、後で異なるファイル記述子でコマンドが開かれる可能性があることです。このコマンドは、必要に応じてfd 0をシーク/ mmapできます。これはcat file | cmd、今回cmdのstdinがmmap /シークできないパイプである場合と混同しないでください。


4
リダイレクションを使用するsortと、データが順番に読み取られmmap、ファイルを読み取ることができなくなることに注意してください。一方でsortそれとあまり問題を持っていない可能性があり、性能を考慮less <fileしてless file。最初の場合lessはファイルの内容全体をメモリに保持する必要があり、2番目の場合は必要な部分のみを読み取ることができます。それfileが100GBのログファイルだと想像してみてください...
発泡スチロールが

7
@styrofoamfly:less <fileすべてのファイルをメモリに保持するのは正しいことですが、強制されているわけではありません。これは以下の欠点です。だけcat file | lessに強制されます。チェックアウトless /dev/fd/0 <fそれは標準入力の上、それを受けていても、メモリ内のファイルを保持しません。Unixの標準入力は探せないというのはよくある誤解です。実際、ファイルの種類によってはシーク可能です。
pts

@styrofoamfly read()ファイルからデータを順番に読み取りながら、ファイルmmap()全体を一度にメモリに読み込むということですか?
ティム

1
@JohnBollingerいいえ。それは、少なくともGNUプロジェクトが開始される前の1980年のSysIIIからのgetoptにまで遡りsort、POSIX を含むほとんどの標準ユーティリティでサポートされる必要があります。しかし、常にサポートされているわけではないのは事実です。
ステファンシャゼラス

2
私の謝罪、@StéphaneChazelas、あなたは規約の起源について正しいです、そして、getopt()C関数のPOSIX仕様が引数のこの重要性を認識することをさらに規定します--。しかし、主なポイントはあなたが受け入れるものです:引数処理は個々のプログラムのドメインであり、すべてが--特別に扱うわけではありません。
ジョンボリンジャー

17

問題は、ダッシュで始まるファイル名です。コマンドが値をオプションとして解釈するためsort "$f1"、の値がでf1始まる場合は機能しません-。通常、これはエラーになりますが、セキュリティホールさえ引き起こす可能性がありますダブルダッシュ引数の平均値「は、この点を超えていないオプション」の値がそれほどオプションとして解釈されることはありません。ただし、エッジケースが1つあります:の値がダッシュで他に何もない場合、それはオプションではなく、引数です。これは、「標準入力」を意味します(引数が入力ファイルであるため; 「標準出力」を意味します)。sort -- "$f1"--f1f1-

リダイレクトを使用すると、これらの落とし穴をすべて回避できます。

これは、だけでなく、ほとんどのコマンドに適用されますsort


sort < "$f1"値が等しい場合に機能すると言っています-か?私が試したどのシェルにもありません。
-grawity

@grawity、と比較seq 10 > -; sort -してくださいseq 10 > -; sort < -
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.