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


61

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

> file1 < file2 cat

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

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

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

なぜcatfile2ですか?cat file2オペランドが正しい順序になっていないことをどのように知るのですか?


11
「正しい順序」とは何ですか?「正しい順序」が記載されているリソース/学習資料へのリンクを提供できますか?
モニカとの軽さのレース

7
このような質問をするときは、シェルを指定する必要があります。特にリダイレクトの場合は、エッジケースが異なるものが異なります。
クリリス

回答:


117

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

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

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

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

$ cat <file2 >file1

と同じです

$ <file2 cat >file1

と同じです

$ <file2 >file1 cat

など¹

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

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

catoperandが指定されている場合、標準入力からも読み取ります-。繰り返しになりますが、これは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リダイレクト]


14
@Steveリダイレクトを自由に移動できるため、一部のコマンドをより明確にすることができます。たとえば、最初に入力リダイレクトを使用するパイプライン<in foo | bar >outはすべてを論理的な順序に並べます。またecho >&2 Something bad happened、シェルスクリプトからのエラー出力が好きです。しかし>out <in cat、単に難読化です

2
どのsort file >fileように正しく達成できますか?
seth10

11
@sethtでsort -o file file
クサラナナンダ

6
素晴らしい答え。順序が重要であることに注意してください。< file1 > file2 catより良いだろう> file2 < file1 cat避けるだろうとfile2場合は切り捨てられfile1開くことができません。
ステファンシャゼラス

3
注意すべき点:HTMLフラグメントを使用してPOSIXにリンクする場合、仕様の同じリビジョンのエディション間でフラグメントが変更されることがわかっているため、正確なエディション(pubs.opengroup.org/onlinepubs/9699919799.2016editionなど)を指定することをお勧めします(私のサイトを含むこのサイトの回答の多くのリンクは、2016年版がリリースされた後、フラグメントが間違った場所を指しているため、現在間違っています)。
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.