web-dev-qa-db-ja.com

&>と2>&1の違いは何ですか

リダイレクトには、標準出力標準エラー標準出力への2つの形式があります。しかし、どちらが良いですか?そして、なぜ&>が完璧と考えられますか?

多くのチュートリアルやbashマニュアルでさえ&>の方が優れていると述べているように、私はその違いを見つけることができません!

なぜ&>ではなく2>&1を使用するのか

主にbashシェルを使用


編集:コメントをありがとう

>&のみがcshまたはtcshで動作します

Kshでは、2>&1のみが機能します。

ダッシュ使用>ファイル2>&1リダイレクトのみ

次に、使用するシェルが何であれ、私のスクリプトが他のシステムと互換性があることを確認するために使用するものはどれですか!

28
Maythux

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シェルコマンド言語標準で指定された機能です。シェル。

出力リダイレクトの正確な意味と意味 も参照してください。

20

私は一般的に 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に関しては、&>と同じように見えます。毎日何か新しいことを学びます。

6
TSJNachos117

から Bashリファレンスマニュアル-> 3.6.4標準出力と標準エラーのリダイレクト

このコンストラクトにより、標準出力(ファイル記述子1)と標準エラー出力(ファイル記述子2)の両方を、Wordの拡張である名前のファイルにリダイレクトできます。

標準出力と標準エラーをリダイレクトするには、2つの形式があります。

&>Word

そして

>&Word

2つの形式のうち、最初の形式が優先されます。 これは意味的にと同等です

>Word 2>&1

2番目のフォームを使用すると、Wordが数字または「-」に展開されない場合があります。存在する場合、互換性の理由から他のリダイレクト演算子が適用されます(下記のファイル記述子の複製を参照)。

入力と出力に関するグレッグのウィキ-> 4.2。ファイル記述子の操作

便宜上、Bashはさらに別の形式のリダイレクトを利用できるようにします。 &>リダイレクト演算子は、実際にここで行った[2>&1];の短縮バージョンです。 stdoutとstderrの両方をファイルにリダイレクトします。

4
fedorqui

なぜ2>&1ではなく&>を使用するのか

2>&1は標準のBourne/POSIXシェルです。

&>はbash拡張であり、de jure標準ではありません。

Bash拡張機能を使用してスクリプトを作成すると、遅かれ早かれ、標準のシェルで実行されているため、不可解な構文エラーメッセージで頭をかくような失敗に遭遇するでしょう。

4
Stephen M. Webb