web-dev-qa-db-ja.com

このコマンドはどのように合法ですか? "> file1 <file2 cat"

file2がすでに存在すると仮定すると、コマンド

> file1 < file2 cat

file2のコンテンツをfile1にコピーしているようです。

しかし、私はこの構造を理解できません。

「何も」がfile1に向けられていることを理解しています(コンテンツの作成または削除)。次に、file2のコンテンツがfile1に送信されます。

catfile2の後にあるのはなぜですか?オペランドが正しい順序でない場合、どのようにcat file2を知るのですか?

61
shaqed

シェルは、コマンドラインでcatコマンドを実行する前に、リダイレクトを探します。

2つのリダイレクトがあります。

  1. >file1これにより、コマンドの標準出力がfile1に送られます。
  2. <file2これにより、コマンドの標準入力がfile2から取得されます。

これらのリダイレクトがコマンドラインの不安定な場所に配置されているという事実は重要ではありません。

$ cat <file2 >file1

と同じです

$ <file2 cat >file1

それは同じです

$ <file2 >file1 cat

など¹

これらすべてのインスタンスのcatユーティリティは、コマンドライン引数なしで実行されることに注意してください。リダイレクトはcatコマンドのオペランドではなく、コマンドへのリダイレクトとコマンドからのリダイレクトをセットアップするためのシェルへの指示です(標準の入力と出力をファイルに接続します)。シェルは、コマンドを呼び出す前にbeforeリダイレクトを設定します。

cat filecat <file(または、必要に応じて<file cat)の違いは、最初のケースでは、catユーティリティ自体がファイルを開いていることです。コマンドラインでオペランドとして指定して読み取りを行う場合、2番目の場合、Shellはファイルを開いてcatを接続しますit²への入力ストリーム。 2番目のケースでは、catはファイルオペランドが指定されていないことに気づき、自動的に標準入力からの読み取りに切り替えます。これはcatおよびその他のユーティリティの機能であり、すべてのユーティリティが行う機能ではありません。

catには、オペランド-が指定されている場合、標準入力からも読み取ります。繰り返しますが、これはcatと他のいくつかのユーティリティにのみ特別です(つまり、Shellが行うことは何もありません)。現在のディレクトリにある名前-であるファイルでcatを使用するには、ファイル名へのパスを追加します。 ./-として。

¹ リダイレクトの順序は、状況によっては依然として重要です。たとえば、cat <file2 >file1を使用すると、file1にアクセスできない場合、file2は切り捨てられません(リダイレクトは左から右に解析されます)。ただし、Wordの相対配置catは任意であり、これには影響しません。

² 猫は存在しないファイルを開くと別のエラーを出します 」の質問も参照してください。


シェルがコマンドラインでコマンドを実行する前にリダイレクトをセットアップするという事実が、これらのようなことが失敗し、最終的に空の出力ファイルになる:

$ sort file >file

ここで、シェルはsort fileを実行してfileの標準出力をファイルに接続する前に、ファイルsortを切り捨てます(空にします)。 sortユーティリティはfileを開き、その内容をソートします(何もありません)。結果(なし)は、標準出力ストリームを介してfileに渡されます。

この特定の場合の解決策(「インプレース」でファイルをソートする場合)は

$ sort -o file file

または

$ sort file >file.sorted && mv file.sorted file

これは、-oファイルを使用して出力ファイル名を指定するときにsortが行うこととほぼ同じです。


コマンドラインで、リダイレクトがユーティリティの実際の名前の前に来る可能性があるというステートメントをバックアップするだけです。

「単純なコマンド」は、オプションの変数の割り当てとリダイレクトのシーケンスであり、任意の順序で続き、オプションで単語とリダイレクトが続き、制御演算子によって終了されます。 [ref:POSIX Shell Command Language 2.9.1 Simple Commands]

また、リダイレクトはユーティリティのオペランドの一部ではありません。

オプションの番号、リダイレクト演算子、およびWordは、実行するコマンドに指定された引数(存在する場合)に表示されません。 [ref:POSIX Shell Command Language 2.7 Redirection]

118
Kusalananda