file2
既に存在すると仮定すると、コマンド
> file1 < file2 cat
のコンテンツをにコピーしているfile2
ようfile1
です。
しかし、この構造は理解できません。
「何も」がに向けられていることを理解していますfile1
(コンテンツの作成または消去)。次に、のコンテンツfile2
はに向けられていfile1
ます。
なぜcat
後file2
ですか?cat file2
オペランドが正しい順序になっていないことをどのように知るのですか?
file2
既に存在すると仮定すると、コマンド
> file1 < file2 cat
のコンテンツをにコピーしているfile2
ようfile1
です。
しかし、この構造は理解できません。
「何も」がに向けられていることを理解していますfile1
(コンテンツの作成または消去)。次に、のコンテンツfile2
はに向けられていfile1
ます。
なぜcat
後file2
ですか?cat file2
オペランドが正しい順序になっていないことをどのように知るのですか?
回答:
シェルは、cat
コマンドラインでコマンドを実行する前に、リダイレクトを探します。
2つのリダイレクトがあります。
>file1
これにより、コマンドの標準出力がに移動しfile1
ます。<file2
これにより、コマンドの標準入力がから取得されfile2
ます。これらのリダイレクトがコマンドラインの不安定な場所に配置されるという事実は重要ではありません。
$ cat <file2 >file1
と同じです
$ <file2 cat >file1
と同じです
$ <file2 >file1 cat
など¹
cat
これらすべてのインスタンスのユーティリティは、コマンドライン引数なしで実行されることに注意してください。リダイレクトはcat
コマンドのオペランドではなく、コマンドへのリダイレクトとコマンドからのリダイレクトをセットアップするためのシェルへの指示です(標準入力と出力をファイルに接続します)。シェルは、コマンドを呼び出す前にリダイレクトを設定します。
cat file
and cat <file
(または、もしそうなら<file cat
)の違いは、最初のケースでは、cat
ユーティリティ自体がファイルを開いていることです。ファイルは、コマンドラインでオペランドとして指定され、読み取り用です。2番目のケースでは、シェルはファイルを開き、cat
の入力ストリームをit²に接続します。2番目のケースでcat
は、ファイルオペランドが指定されていないことがわかり、標準入力からの読み取りに自動的に切り替わります。これはcat
、およびその他のユーティリティの機能であり、すべてのユーティリティの機能ではありません。
cat
operandが指定されている場合、標準入力からも読み取ります-
。繰り返しになりますが、これはcat
他のいくつかのユーティリティ(シェルが実行しないもの)に対してのみ特別です。cat
名前がの 現在のディレクトリ内のファイルで使用するには-
、などのファイル名へのパスを追加します./-
。
¹ 状況によっては、リダイレクトの順序が依然として重要です。でcat <file2 >file1
、例えば、file1
場合切り捨てられませんfile2
アクセスできない(リダイレクションを左から右に解析されます)。cat
ただし、単語の相対的な配置は依然として任意であり、これには影響しません。
² また、「存在しないファイルを開くときに猫が別のエラーを出す」という質問も参照してください。
コマンドラインでコマンドを実行する前にシェルがリダイレクトを設定するという事実が、これらのようなものが失敗し、空の出力ファイルで終わる理由です:
$ sort file >file
ここで、シェルはをfile
実行してファイルの標準出力をsort file
接続する前にファイルを切り捨てます(空sort
にします)。sort
ユーティリティが開きますfile
と(何物でもありません)、その内容を並べ替えます。結果(なし)は、標準出力ストリームを介してに渡されfile
ます。
この特定の場合の救済策は(「インプレース」ファイルをソートするため)
$ sort -o file file
または
$ sort file >file.sorted && mv file.sorted file
これはsort
、-o
ファイルを使用して出力ファイル名を指定するときの動作とほぼ同じです。
コマンドラインでリダイレクトがユーティリティの実際の名前に先行する可能性があるというステートメントをバックアップするだけです:
「単純なコマンド」は、オプションの変数の割り当てとリダイレクトのシーケンスであり、任意のシーケンスで、オプションで制御演算子によって終了されるワードとリダイレクトが続きます。[参照:POSIXシェルコマンド言語2.9.1単純なコマンド]
また、ユーティリティのオペランドの一部ではないリダイレクトについても:
オプションの番号、リダイレクト演算子、および単語は、実行するコマンドに提供された引数(存在する場合)には表示されません。[参照:POSIXシェルコマンド言語2.7リダイレクト]
<in foo | bar >out
はすべてを論理的な順序に並べます。またecho >&2 Something bad happened
、シェルスクリプトからのエラー出力が好きです。しかし>out <in cat
、単に難読化です
sort file >file
ように正しく達成できますか?
sort -o file file
。
< file1 > file2 cat
より良いだろう> file2 < file1 cat
避けるだろうとfile2
場合は切り捨てられfile1
開くことができません。