出力を会話ツールにリダイレクトしてstderrを取得する

出力を会話ツールにリダイレクトしてstderrを取得する

リンクを取得するためにPythonファイルを使用していますが、それには時間がかかり、印刷され、通常、リンクは次のように33stderr66100印刷されます。sys.write.stderr(var)

今このコマンドを実行したいと思います。python file.py | dialog --gauge "Doing stuffs" 10 35 0

stdout(更新率の場合は33、66、100)をパイプして変数のsterrを測定してインポートしたいと思います。

{ 
    python3 file.py 2>&3 | dialog --gauge "Doing stuffs" 10 35 0; 
} 3>&1

このコマンドはダイアログボックスを正しく実行してからstderrを出力しますが、サブシェルで実行しないと出力を取得できません。ただし、これを行うとダイアログボックスが消えます。

答え1

最も簡単な方法は、標準エラーをファイルに保存し、スクリプトが完了した後にそのファイルの内容を変数に割り当てることです。

python file.py 2> ErrorFile | dialog --gauge "Doing stuffs" 10 35 0
MY_STDERR=$(<ErrorFile)

中間ファイルを使用したくない場合は、ここに別の方法があります。この回答、指示も見ることができます):

{ MY_STDERR="$( { python file.py | dialog --gauge "Doing stuffs" 10 35 0; } 2>&1 1>&3 3>&- )"; } 3>&1;

答え2

パーセントを記録するこの関数定義を試してみましょう。標準出力そしてコメント標準エラー、あなたのプログラムの代替としてpython

thing() { for f in {10..100..10}; do sleep 0.5; echo "$f"; echo "Got $f" >&2; done; }

キャプチャできます標準エラーthingまだレンダリングされたデバイスを使用した出力:

{ info=$( ( thing 2>&4 | dialog --gauge 'Gauge' 10 40 0 >&3 ) 4>&1 ) ; } 3>&1
printf "GOT> %s\n" "$info"

ここで私たちはthingキャプチャします標準エラー到着FD 4dialog --gauge、一時的に出力を次に送信します。FD 3。変数を割り当てた$infoFD 4私たちはリダイレクトFD 3に戻る標準出力。最終的な再割り当てが不要な場合は、外側の中かっこを削除してリダイレクトして、機器のディスプレイを開いたままにして式を簡素化できます。標準エラー:

info=$( ( thing 2>&4 | dialog --gauge 'Gauge' 10 40 0 >&2 ) 4>&1 )
printf "GOT> %s\n" "$info"

答え3

別のオプションは次のとおりです。

x=$( { dostuff | 
       dialog --gauge "Doing stuffs" 10 35 0 >/dev/tty 2>/dev/null; } 2>&1 )

ここでは、

  • 進行状況バーの標準出力は、他のものをバイパスdialogして端末に直接リダイレクトされます。
  • stderrがdialog送信され、/dev/nullそこからゴミを捕まえません。
  • の標準出力は通常通りパイプで接続されていますpythondialog
  • stderr は、pythonコマンド置換によって提供される「stdout」にグループ外にリダイレクトされ、シェルによってキャプチャされます。

もちろん、リダイレクトとは、出力/dev/tty全体が別の場所にリダイレクトされても進行状況バーが印刷されることを意味します。これは必要なものでもそうでないかもしれません(ただし、出力された端末制御コードの混乱は、端末を除くdialogどこでも非常に便利なものかもしれません)。

これによりエラーも非表示になりますが、割り当て全体dialogの終了状態はパイプラインの最後のコマンドの終了状態であるため、確認できます。または、set -o pipefailパイプラインのコマンドが失敗したことを確認してください。

テストするには、次のスクリプトを使用しますdostuff

#!/bin/bash
for x in 0 1 2 3 4 5; do
    echo $((x * 20));
    sleep .5;
done
echo "this is the result" >&2

関連情報