リダイレクトには、標準出力と標準エラーの標準出力への2つの形式があります。しかし、どちらが良いですか?そして、なぜ&>
が完璧と考えられますか?
多くのチュートリアルやbashマニュアルでさえ&>
の方が優れていると述べているように、私はその違いを見つけることができません!
なぜ&>
ではなく2>&1
を使用するのか
主にbash
シェルを使用
編集:コメントをありがとう
>&のみがcshまたはtcshで動作します
Kshでは、2>&1のみが機能します。
ダッシュ使用>ファイル2>&1リダイレクトのみ
次に、使用するシェルが何であれ、私のスクリプトが他のシステムと互換性があることを確認するために使用するものはどれですか!
Bashのmanページには、リダイレクトする2つの方法があります stderrとstdout :&> file
と>& file
。ここで、stderrとstdoutの両方が表示されていることに注意してください。
この>file 2>&1
の場合、stdout(1)のファイルへのリダイレクトを行っていますが、stderr(2)をstdoutと同じ場所にリダイレクトするように指示しています!そのため、目的は同じかもしれませんが、考え方は少し異なります。言い換えると、「ジョン、学校に行って、サッジーはジョンが行ったところに行く」。
好みはどうですか? &>
はbash
のことです。したがって、スクリプトを移植する場合、それは実行されません。ただし、スクリプトがbashを使用するシステムでのみ動作することを100%確信している場合は、優先順位はありません。
UbuntuのデフォルトであるDebian Amquist Shellであるdash
の例を次に示します。
$ grep "YOLO" * &> /dev/null
$ grep: Desktop: Is a directory
grep: Documents: Is a directory
grep: Downloads: Is a directory
grep: Music: Is a directory
grep: Pictures: Is a directory
grep: Public: Is a directory
grep: Templates: Is a directory
grep: Videos: Is a directory
grep: YOLO: Is a directory
grep: bin: Is a directory
ご覧のとおり、stderrはリダイレクトされていません
質問の編集に対処するには、ifステートメントを使用して$ Shell変数を確認し、それに応じてリダイレクトを変更できます
ただし、ほとんどの場合、> file 2>&1
は機能するはずです
より技術的な用語では、[integer]>&Word
という形式は Duplicating Output File Descriptor と呼ばれ、POSIXシェルコマンド言語標準で指定された機能です。シェル。
出力リダイレクトの正確な意味と意味 も参照してください。
私は一般的に Bourne-again Shell のやり方に従うことをお勧めします。bashは間違いなく最も人気のあるUnixシェルだからです。 Bashは通常、&>
または2>&1
のいずれかを使用します。私見、どちらも「完璧」ではないので、私はそのナンセンスを忘れることをお勧めします。現実的には、どちらを使用すべきかは、何をしようとしているかによって異なります。
2>&1
は、stderrをstdoutとマージします。これは、たとえば、stderrテキストをパイプする場合に便利です。したがって、たとえば、プログラムが特定のstderrメッセージを出力するかどうかを確認したいが、(おそらく)重要でないゴミで画面がいっぱいにならないようにするには、stdoutを検索するprogram 2>&1 | grep crashed
のようなことを行うことができますそして、「クラッシュ」したWordの「プログラム」と呼ばれるプログラムのstderr。
一方、プログラムに何も印刷させたくない場合は、program &> /dev/null
を実行するだけで、stderrとstdoutの両方を/ dev/nullにリダイレクトできます。 。または、プログラムの出力を保存する場合(おそらくバグなどを報告するため)、stderrとstdoutの両方をファイルにリダイレクトできます。program &> log.txt
はすべてのデータを "log.txtというファイルにリダイレクトします「。必要に応じて、program 2> log.txt > log.txt
またはprogram 2>&1 | cat > log.txt
を介してstdoutとstderrをリダイレクトできます。どちらも&>
を使用した場合と同じ効果があります。 program 2>&1 > file
などの操作を行うと、stdoutのみがリダイレクトされますが、stderrは、上記のようにリダイレクトできるcatなどの別のプログラムにパイプすることができます。ただし、&>
と入力する方が、上記の例のいずれよりも簡単です。入力する文字数が少なくなるため(人間にとっても読みやすくなります)。 program 2> log.txt > log.txt
は、bash以外のシェルで動作する可能性が高いことに注意してください。
PS:他のシェルを使用している人が心配な場合は、「マジックナンバー」または「シェバン」と呼ばれるスクリプトの最初の行に追加できるものがあります。これは基本的に、他のコンピューター(特にUnix系のオペレーティングシステムを実行しているコンピューター)がスクリプトの実行に使用するプログラムを認識できるようにする方法です。異なるスクリプトは異なるシバンを使用します。 bashスクリプトのシバンは次のようになります。
#!/bin/bash
特定のスクリプトの最初の行として上記を使用する場合、通常はbashを使用してそのスクリプトを実行します。これにより、誰かが間違ったシェルを使用してスクリプトを誤って実行することがはるかに困難になります。
PS:嘘をつくつもりはありません。今まで>&
を使用できるとは知りませんでしたが、bashに関しては、&>
と同じように見えます。毎日何か新しいことを学びます。
から Bashリファレンスマニュアル-> 3.6.4標準出力と標準エラーのリダイレクト :
このコンストラクトにより、標準出力(ファイル記述子1)と標準エラー出力(ファイル記述子2)の両方を、Wordの拡張である名前のファイルにリダイレクトできます。
標準出力と標準エラーをリダイレクトするには、2つの形式があります。
&>Word
そして
>&Word
2つの形式のうち、最初の形式が優先されます。 これは意味的にと同等です
>Word 2>&1
2番目のフォームを使用すると、Wordが数字または「-」に展開されない場合があります。存在する場合、互換性の理由から他のリダイレクト演算子が適用されます(下記のファイル記述子の複製を参照)。
入力と出力に関するグレッグのウィキ-> 4.2。ファイル記述子の操作 :
便宜上、Bashはさらに別の形式のリダイレクトを利用できるようにします。 &>リダイレクト演算子は、実際にここで行った[
2>&1
];の短縮バージョンです。 stdoutとstderrの両方をファイルにリダイレクトします。
なぜ2>&1ではなく&>を使用するのか
2>&1
は標準のBourne/POSIXシェルです。
&>
はbash拡張であり、de jure標準ではありません。
Bash拡張機能を使用してスクリプトを作成すると、遅かれ早かれ、標準のシェルで実行されているため、不可解な構文エラーメッセージで頭をかくような失敗に遭遇するでしょう。