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


30

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

多くのチュートリアルやbashマニュアルの状態&>がより優れているように、違いが何であるかを見つけることができません !

なぜ使用&>しないで2>&1

主にbashシェルを使用


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

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

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

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

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


より良いのは、あなたが何をする必要があるかということです。これらは非常に異なることを行います。どのシェルを使用していますか?
スカペレン

bashを使用して@Skaperen
Maythux

1
何をあなたが達成したいですか?
スカペレン

私はちょうど私がしたいことの両方にいけないです、違いが何であるかを知りたいが、私は一度だけ、他の上preffredされるように違いあるかどうかを知る必要があり
Maythux

2
&> somewhereは単にbashの短縮形です。bash> somewhere 2>&1マニュアルの言葉では、 「シンボリックに同等」です
-steeldriver

回答:


23

Bashのmanページには、stderrとstdoutをリダイレクトする方法が2つあります: &> file>& file。ここで、stderrとstdoutの両方が表示されていることに注意してください。

この場合、>file 2>&1stdout(1)をファイルにリダイレクトしますが、stderr(2)をstdoutと同じ場所にリダイレクトするように指示しています!そのため、目的は同じかもしれませんが、考え方は少し異なります。言い換えると、「ジョン、学校に行って、サッジーはジョンが行ったところに行く」。

好みはどうですか?&>であるbash事。したがって、スクリプトを移植する場合、それは実行されません。ただし、スクリプトがbashを使用するシステムでのみ動作することを100%確信している場合は、優先順位はありません。

dashUbuntuのデフォルトであるDebian Amquist Shellの例を次に示します。

$ 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]>&wordDuplicateating Output File Descriptorと呼ばれ、POSIXシェルコマンド言語標準で指定された機能であり、ほとんどのPOSIX準拠およびBrourneのようなシェルでサポートされています。

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


次に、他のシェルで使用するとどうなりますか?
Maythux

zshサポート&>.... @Maythux サポートしていないシェルでは、&>たとえばdash、単純な>file 2>&1リダイレクトを使用する必要があります。
heemayl

次に、スクリプトが異なるシェルと互換性があることを確認したい場合に使用するもの
-Maythux

3
@Maythux Use >file 2>&1。すべてのシェルでこの作業
Sergiy Kolodyazhnyy

1
/etc/passwd各ユーザーに設定される@ TSJNachos117シェルは、対話型のシェルです。システムスクリプトは、dash 特に指定がない限り、通常使用されます。デフォルトは、/bin/shUbuntuの場合にシンボリックリンクされているものによって決まりますdash。RHELではあるのですbashFreeBSDの中でそれは、tcsh ソース別のソース
Sergiy Kolodyazhnyy

6

bashは間違いなく最も人気のあるUnixシェルであるため、一般的にBourne-again SHellのやり方に従うことをお勧めします。Bashは通常、&>またはのいずれかを使用します2>&1。私見、どちらも「完璧」ではないので、私はそのナンセンスを忘れることをお勧めします。現実的には、どちらを使用すべきかは、何をしようとしているかによって異なります。

2>&1stderrをstdoutにマージします。これは、たとえば、stderrテキストをパイプする場合に役立ちます。したがって、たとえば、プログラムが特定のstderrメッセージを出力するかどうかを確認したいが、画面に(おそらく)重要でないゴミを入れたくない場合はprogram 2>&1 | grep crashed、プログラムからstdoutとstderrを検索するようなことができます「クラッシュ」という言葉を「プログラム」と呼びます。

一方、プログラムに何program &> /dev/nullも出力させたくない場合は、単に実行するだけで、stderrとstdoutの両方を/ dev / nullにリダイレクトできます。または、プログラムの出力を保存したい場合(おそらくバグなどを報告するため)、stderrとstdoutの両方をファイルprogram &> log.txtにリダイレクトできます。すべてのデータを「log.txt」というファイルにリダイレクトします。必要に応じて、program 2> log.txt > log.txtまたはを使用してstdoutとstderrをリダイレクトできますprogram 2>&1 | cat > log.txt。どちらもを使用した場合と同じ効果があり&>ます。のような操作を行うとprogram 2>&1 > file、stdoutのみがリダイレクトされますが、stderrは、上記のようにリダイレクトできるcatなどの別のプログラムにパイプすることができます。ただし、タイピング&>入力する文字数が少ないため、上記の例のいずれよりも簡単です(人間が読むのが少し簡単です)。program 2> log.txt > log.txt非bashシェルで動作する可能性が高いことに注意してください。

PS:他のシェルを使用している人が心配な場合は、「マジックナンバー」または「シバン」と呼ばれるスクリプトの最初の行に追加できるものがあります。これは基本的に、他のコンピューター(特にUnix系のオペレーティングシステムを実行しているコンピューター)がスクリプトの実行に使用するプログラムを認識できるようにする方法です。異なるスクリプトは異なるシバンを使用します。bashスクリプトのシバンは次のようになります。

#!/bin/bash

上記のスクリプトの最初の行として上記を使用する場合、通常、bashを使用してスクリプトを実行します。これにより、誰かが誤ったシェルでスクリプトを誤って実行することがはるかに困難になります。

PS:私は嘘をつくつもりはありません:今まで、私は使用できるとは知りませんでした>&が、bashに関しては、それはと同じように思われます&>。毎日何か新しいことを学びます。


#!明示的に要求するためのlineの使用については同意しますがbash、他のシステムでは常に使用できるとは限りません。多くの場合、開発者/システム管理者は、bash利用できない可能性があり、インストールの制御下にないシステム用のポータブルスクリプトを記述する必要がありますbash>file 2>&1ただ多くのポータブルです。
セルギーコロディアズニー16

上記の逆のエラーを行ったが、それはあなたが主張したい、または望む結果をもたらさない。stderrをstdoutにリダイレクトしてから、stdoutをリダイレクトすると、stderrは元のstdoutのままになります。
ubfan1

Serg:bashが普遍的であると示唆するつもりはありませんでした。ただし、(t)cshよりも多くの人が使用していると思います。他の人が何を使用しているかわからず、盲目的に推測する必要がある場合、bashがおそらく最善の策です。また、bashのみを使用しているため、一般的に移植性については知りません。>file 2>&1よりポータブルであるという事実は知っておくと良いでしょう。それを反映するように編集します。
TSJNachos117

Ubfan1、情報をありがとう。その場合、bashがstderrをファイルにリダイレクトしないと100万年も推測することはありませんでした。他の人が同じ間違いをしないように、回答を編集しました。
TSJNachos117

4

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

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

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

&>word

そして

>&word

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

>word 2>&1

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

また、入力と出力に関するGregのwikiを参照することもできます-> 4.2。ファイル記述子の操作

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


4

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

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

&>bash拡張機能であり標準ではありません。

bash拡張機能を使用してスクリプトを記述した場合、遅かれ早かれ、標準シェルで実行されているため、不可解な構文エラーメッセージで頭をかくような障害が発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.