このコマンドはどのように合法ですか? ">ファイル1 <ファイル2猫"

このコマンドはどのように合法ですか? ">ファイル1 <ファイル2猫"

file2すでに存在すると仮定すると、次のコマンドは

> file1 < file2 cat

file2コンテンツがにコピーされているようですfile1

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

私は「なし」の目的がfile1(コンテンツの作成または削除)であることを理解しています。これでコンテンツfile2がに移動しますfile1

なぜcatその後file2cat file2オペランドの順序が間違っているかどうかはどうすればわかりますか?

答え1

シェルは、catコマンドラインからコマンドを実行する前にすべてのリダイレクトを処理します。リダイレクトには、<(stdin、読み取り専用)、<>(stdin、読み取り+書き込み)、>>>stdout、書き込み専用)、および(stdout、書き込み専用、追加出力)を使用した入力または出力リダイレクトが含まれ、(ここではドキュメント)<<wordも含まれます。そして<<<'...'(一部のシェルでは「ここの文字列」)。入力または出力をリダイレクトする効果を得るには、これらのリダイレクト演算子を引用符で囲む必要があり、デフォルト値(演算子に応じてstdin(0)またはstdout(1))の代わりにリダイレクトするファイル記述子を指定するために数字を前に追加できます。 。

表示されるコマンドには2つのリダイレクトがあります。

  1. >file1 これにより、コマンドの標準出力がに移動しますfile1
  2. <file2 これにより、コマンドの標準入力が表示されますfile2

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

$ cat <file2 >file1

同じですか?

$ <file2 cat >file1

これは次のとおりです。

$ <file2 >file1 cat

しばらく¹

catこれらすべてのインスタンスのユーティリティは、次のように実行されます。コマンドライン引数なし。リダイレクトはcatコマンドのオペランドではなく、コマンドとのリダイレクトを設定するシェルのガイドラインです(標準の入力と出力をファイルに関連付けます)。シェル設定リダイレクト今後コマンドを呼び出します。

cat filecat <file(または好む場合)の違い<file catは、最初の場合catはユーティリティ自体が読み取り用にファイル(コマンドラインでオペランドとして提供されます)を開き、2番目の場合はユーティリティ自体が開かれることです。読み取るためにファイルを開きます。シェルファイルを開き、cat入力ストリームをファイルにリンクします²。 2番目のケースでは、catファイルオペランドは提供されず、自動的に標準入力読み取りに切り替わります。これはcat他のユーティリティの機能でもありますが、すべてのユーティリティにこの機能があるわけではありません。

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

1場合によっては、リダイレクトの順序が依然として重要です。たとえば、接続できないcat <file2 >file1場合はfile1切り捨てられませんfile2(リダイレクトは左から右に解析されます)。しかし、単語の相対的な位置はcatランダムであり、これには影響しません。

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


実際、シェルはコマンドラインからコマンドを実行する前にリダイレクトを設定するため、これらの操作は失敗し、空の出力ファイルが生成されます。

$ sort file >file

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

この特別なケース(ファイルを「所定の位置」にソートする場合)の回避策は次のとおりです。

$ sort -o file file

または

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

または、元のファイルが削除されていないことを確認するには(一部のファイルメタデータを保存するため)

$ cp file file.unsorted && sort file.unsorted >file && rm -f file.unsorted

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


コマンドラインでユーティリティの実際の名前の前に来ることができるステートメントのリダイレクトをサポートする(強調表示):

「単純なコマンド」は、一連のオプションの変数の割り当てとリダイレクトです。どんな順序でも、オプションで単語とリダイレクトが続き、制御演算子で終了します。[注:POSIXシェルコマンド言語2.9.1シンプルコマンド]

また、ユーティリティオペランドの一部ではないリダイレクトについて:

オプションの数値、リダイレクト演算子、および単語は、実行するコマンドに指定された引数(存在する場合)には表示しないでください。[参照:POSIXシェルコマンド言語2.7リダイレクト]

関連情報