GNU/Linux >> Linux の 問題 >  >> Linux

Bashリダイレクト構文とその出力を理解しようとしていますか?

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

stdoutをリダイレクトするためのさまざまな構文をテストしてきました およびstderr 同じファイルに保存しますが、すべてが同じ結果になるわけではありません。

たとえば、存在しない2つのファイルを一覧表示しようとすると(file1 および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 、キャリッジリターンが含まれます)、したがって、stderrの最初の6文字 (ls: castdoutによって上書きされました 。
つまり、実際には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が間違っているのですか?それは正確に何を伝えているのか(または 構文#2とは対照的にシェルに実行するように指示しますか?

関連:Bashの$(…)と `…`の違いは何ですか?

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

ありがとうございます!

承認された回答:

2つのプロセスを実行して同じファイルに同時に書き込むのと同じです…悪い考えです。 2つの異なる開いているファイルハンドルができてしまい、データが文字化けする可能性があります(上記の#3の場合と同様)。構文#2の使用は正しいです。 1つになります ファイルハンドルを使用して、stderrとstdoutの両方を同じ場所にポイントします。

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


Linux
  1. イオリダイレクションとヘッドコマンド?

  2. Bash を使用してファイルを検索してコピーする

  3. bashでパスと拡張子なしでファイルのベース名を抽出します

  1. Linuxのルートでもファイルとディレクトリを削除できないようにする方法

  2. Linuxリアルタイムシナリオとそのソリューションの問題

  3. Linuxでの入出力とエラーリダイレクトの操作

  1. Bashに入力されたすべてのコマンドとすべてのファイル操作をログに記録する方法は?

  2. Linux のパイプとリダイレクト - 解説!

  3. エイリアス コマンドを bash スクリプトまたは .bashrc ファイルで機能させる方法