Bashリダイレクトの構文とその出力を理解してください。

Bashリダイレクトの構文とその出力を理解してください。

私はLinuxに初めてアクセスし、リダイレクトがどのように機能するかを理解しようとしています。

同じファイルにリダイレクトするためのさまざまな構文をテストしましたが、すべて同じ結果を生成するわけではありませんstdoutstderr

file1たとえば、存在しない2つのファイル(およびfile2)と2つのファイル(fooおよびfz)を一覧表示しようとすると、次のようになります。

文法#1(リダイレクトなし):

$ ls file1 foo fz file2

これは端末から得られる出力です。

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo  fz

構文#2:

今リダイレクトを通して:

$ ls file1 foo fz file2 > redirect 2>&1

このredirectファイルには構文#1と同じ結果が含まれています。

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

したがって、上記の両方の構文はシェルがstderr最初に印刷され、次にstdout

構文#3:

次の構文のいずれかを使用しようとすると、次のようになります。

$ ls file1 foo fz file2 > redirect 2> redirect

または

$ ls file1 foo fz file2 2> redirect > redirect

これにより、ファイルredirectには次の内容が含まれます。

foo
fz
nnot access file1: No such file or directory
ls: cannot access file2: No such file or directory

stdoutここでは以前に印刷されたように見えますが、始めはstderr同じstderr文字数で「切り捨てられた」ことがわかりますstdout

の長さstdoutは6文字(foo fzキャリッジリターンを含む)なので、stderrls: ca)の最初の6文字を上書きしますstdout。だから実際には貼ったものではなく、stderr最初に印刷してからstdout印刷したように見えます。stderr

stderrしかし、もしそうなら、私にもっと意味があるでしょう。完全stdout部分的な上書きの代わりに削除して交換してください。

構文#4:

構文#3を修正する唯一の方法は、次に追加の演算子を追加することですstdout

$ ls file1 foo fz file2 >> redirect 2> redirect

または

$ ls file1 foo fz file2 2> redirect >> redirect

結果は構文#2と同じです。

ls: cannot access file1: No such file or directory
ls: cannot access file2: No such file or directory
foo
fz

この記事はこちら構文#3が間違っていることを説明します(おそらく構文#4も間違っているでしょう)。しかし、議論のために構文#3が間違っているのはなぜですか?一体何を言っているのでしょうか(あるいはいいえTell)シェルに構文#2以外の操作を実行させますか?

stderrまた、出力が常に以前に表示される理由はありますかstdout

ありがとうございます!

ベストアンサー1

これは、同じファイルに同時に書き込む2つのプロセスを実行するのと同じです。これは悪い考えです。 2つの異なるオープンファイルハンドルが発生し、データが歪む可能性があります(上記の#3を参照)。構文#2を使用するのは正しいです。一つファイルハンドルを使用して、stderrとstdoutを同じ場所にポイントします。

stderrが常に最初に印刷されるという規則はありません。私は、lsこれがls特定のファイルが存在しないことを実際に宣言する前に、ディレクトリ内のすべてのエントリをチェックする必要があるためだと思います。したがって、ディレクトリテーブルを介してN回パスするのではなく、単一パスを作成し、指定されたすべてのコマンドライン引数を確認し、エラーを報告し、見つかったファイルを印刷します。他のコマンドはstdoutの後にstderrで印刷することも、それらの間を交互に印刷することもできます。

おすすめ記事