web-dev-qa-db-ja.com

リダイレクトを伴うコマンド内のスペース

program 2> error.log 
program &> filename 
program >> filename 2>&1
program 2>&1

これらの行の意味を理解することができました。

ただし、スペースをどこに置くべきかはよくわかりません。また、実際にスペースを配置する場所が問題にならないことも心配です。読んでくれてありがとう。

5
Smile

はい、単語とリダイレクトの間隔は関係ありません。それは簡単な答えです。

詳細は、Shell(簡単にするためにbashのみを参照)が特定の文字と文字のグループを「単語」と「メタ文字」として扱うという事実にあります。 bash 4.3マニュアルから:

メタキャラクター

引用されていないときに単語を区切る文字。次のいずれか:

|  & ; ( ) < > space tab

そして

単語シェルによって単一のユニットと見なされる一連の文字。トークンとも呼ばれます。

そのため、次のことを行います。

$ echo "hello world">/dev/null

または

$ echo "hello world" > /dev/null

まだ3つの単語(引用符で囲まれているため、「hello world」は単一のシェルワードと見なすことができます)に、1つの>メタ文字とカップルスペースがあります。シェルはそれを確認し、最初にリダイレクトを実行します(したがって、最初にメタ文字を検索します)。その後、標準の動作に従ってコマンドを実行します。

ただし、特に2>&1などのファイル記述子を複製する場合は、リダイレクトの順序が重要になります。 stderrとstdinの両方を同じ場所に送信したいとします。間違った方法は次のとおりです。

$ stat ./non-existent file 2>&1  > /dev/null
stat: cannot stat './non-existent': No such file or directory
stat: cannot stat 'file': No such file or directory

ファイル記述子2を端末の1と同じ場所に出力していますが、すでにそうしています。そのため、stderrが表示されます。

最初にstdoutをリダイレクトし、その後で2が指す場所を変更した場合-それは動作します:

$ stat ./non-existent file > /dev/null 2>&1 
7