Linuxの少ない動作とstderr


11

で複雑なコマンドの出力を監視しています。less問題は、stderr失われることです。stderr行は通常、stdout内の行の間にリストされlessます。それらをコンソールに出力し、終了時にlessそれらを一緒に表示したいと思います。

私はこれに対する解決策がないかもしれないことに気づきました、私は読んで、teeそしてmultitee今のところ運がありません。


2
stderrをstdoutにリダイレクトする方法を教えてくれましたが、それは私が望んでいたことではありません。stderrがlessの内部でstdoutと混ざりたくない。終了時にstderrがターミナルにあるようにしたいと思います。

場合stderrにリダイレクトされstdout、へのすべての出力がstderr されます上の通常の出力と混合することstdout。出力をパイプするlessと、両方が表示されます。
一部のプログラマー、

「終了時にstderrがターミナルに表示される」を無視する場合は、Ctrl-Lを押しlessて画面を再描画することをお勧めします。
かまえ

回答:


10

多分

command 2> command.err | less; cat command.err; rm command.err

補遺

以下は、質問を注意深く読むことを怠り、上記のOPの明確なコメントを読んでいない人々のための説明です。

haelixが指摘しました:

stderr行は通常、less内のstdout行の間にリストされます

そして、初期の回答者へのコメントで、

stderrをstdoutにリダイレクトする方法を教えてくれましたが、それは私が望んでいたことではありません。stderrがlessの内部でstdoutと混ざりたくない。終了時にstderrをターミナルに入れたい

問題はおそらくプラットフォーム固有であり、それは確かに古いUnix SVR4プラットフォームで経験したものです。

そのようなプラットフォームで、次のようなことをした場合

 find / ... | less

エラーメッセージ(ディレクトリのアクセス許可など)は次のように表示されます

 stdout line 1
 stdout line 2
 error message text
 stdout line 4

エラーメッセージによって出力行が不明瞭になるようにします。

ページを更新すると、出力行は正しく表示されますが、エラーメッセージは失われます。閉じると、コマンドプロンプトを除いて画面がクリアされます。

あなたが何かをした場合

  find / ... 2>&1 | less

エラーメッセージは標準出力と混在しています。もう一度終了すると、画面は空になります。

最初にlessで標準出力のみを熟読し、次にlessを終了した後にエラーメッセージを表示する場合は、別の解決策が必要です。

それが、私が元の2行の回答で暫定的に提案していたことです。


これはゴミです。ヨアヒムの答えは受け入れられるべきです。
Vanilla Face

2
@VanillaFace:解答に明確な資料を追加しました。
RedGrittyBrick 2016年

15

あなたは、リダイレクトする必要があるstderrstdout

$ ./somecommad 2>&1 | less

シェルのマニュアルを確認してください(例:)man bash


1
この古い質問の新しい読者へのコメント(特にJoachimは対象外)これは、質問を最初にスキャンしたときに誰もが思うことです。しかし、問題はもっと微妙です-dmckeeの回答の
RedGrittyBrick

1

シェルにfd 2をfd 1にリダイレクトするように指示するだけです(stderrからstdoutへ)。

 make 2>&1 | less

1

これまでのすべての回答に欠けていたのは、理由、これがなぜ起こっているのかです。ここでの問題は、端末にデータを出力するプロセスstderrlessそこから出力を表示するプロセスの間のある種の競合状態stdoutです。へのすべての出力が端末に出力された後にlessが表示開始する場合stderr、はそれlessを保持し、を終了しlessた後にメッセージを表示できます。OTOH lessがすでに表示を開始している場合、エラーメッセージlessはの出力と混在し、less終了後は何も保持されlessません(開始前と同じように端末を保持し、間にあるエラーメッセージについて何も知らないため)。

簡単に確認できます。たとえば

grep foo -r /etc | less

すべての "Permission denied"エラーメッセージはless出力と混同され、終了後は何も表示されません。もしあなたがそうするなら

grep foo -r /etc | (sleep 10; less)

すべて(または少なくともほとんど)のエラーメッセージは、less出力を表示する前にターミナルに出力され、後でエラーメッセージが表示されます。

もちろん、通常less、開始する前に10秒間待機する必要はありませんが、Linuxでは待機時間に小数値を指定することもできます。また、高速実行プロセスでは、多くの場合sleep 0.1、競合状態を回避するのに十分なだけの小さな値です。(もちろん、もしあなたが本当に安全な側面を望んでいる、またはしなければならないのであれば、RedGrittyBrickのソリューションを使用してください)。


0

「ファイル記述子」の概念を理解する必要があります。通常、UNIXアプリケーションは3つの特別なファイル記述子から始まります。

  • 標準入力
  • 標準出力
  • 標準誤差

|シェルの「パイプ」は、stdoutあるプロセスからstdin次のプロセスに接続します。

エラーは-設計上- stdin次のプロセスに供給されません。多くの場合、次のアプリケーションでは意味がなく、ユーザーから非表示にしないでください。

エラーをstdoutに混在させたい場合は、egを使用できます2>&1。これにより、「append stderr to stdout」と表示されます。例えば

find /etc 2>&1 | less

アクセスできないファイルからのエラー出力も含める必要があります。

find /etc 2>&1 >/dev/null | less

エラーのみが表示されます。


0

私はあなたの望ましい振る舞いがデフォルトであると私が言える限り、あなたの質問について混乱しています。

私が使うとき

#include <stdio.h>

int main(int argc, char**argv){
  for (int j=0; j<10; ++j){
    fprintf( (j%2 ? stdout : stderr) , "%d\n" , j);
  }
  return 0;
}

簡単なテストを受けるには

$ ./testredirection | less

ちょうどあなたが尋ねるものを行います。なるほど

1
3
5
7
9
(END) 

less

$ ./testredirection | less
0
2
4
6
8
$ 

私がやめたとき less


奇妙なことですが、いつもそういうわけではありません。スクリプト(echo info ; echo error 1>&2)で試し、テストを繰り返します。両方の行がlessにパイプされます。
cYrus

@cYrus:それは私にとっても期待通りに機能します。'コースは、Mac OSボックスで試しました。Bash 3.2.17、394未満。おそらくLinux固有のもの。いずれにしても、RedGrittyBrickのアプローチはうまく機能するはずです。
dmckee ---元モデレーターの子猫

おかしい!Debian Squeeze / Bash 4.1.5 / Less 436
cYrus

ええ、私は職場でScientific Linux 5.3ボックスのシェルを開いて、bash 3.0.15以下382で期待される動作を得ました。そこにリグレッションはありますか?
dmckee ---元モデレーターの子猫

わからないけど、バッファリングの問題だと思う。
cYrus

0

最近、Debian 5.0の1つでこの問題に遭遇しました。たとえば、ls abc | エラーメッセージが少なくなることがわかりました。これは私の知識に反します。

何度か試したところ、これは画面バッファに関連するものにすぎないことがわかりました。stderrは、実際にはあまり入りません。上矢印キーまたは下矢印キー(またはj / k)を使用して説明できます。

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