私はLinuxに初めてアクセスし、リダイレクトがどのように機能するかを理解しようとしています。
同じファイルにリダイレクトするためのさまざまな構文をテストしましたが、すべて同じ結果を生成するわけではありませんstdout
。stderr
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
キャリッジリターンを含む)なので、stderr
(ls: 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で印刷することも、それらの間を交互に印刷することもできます。