2つの別々のストリームにstdoutとstderrを表示する

2つの別々のストリームにstdoutとstderrを表示する

私はstdoutとstderrがインターリーブされずに簡単に識別できるように視覚的に分離する方法を探しています。理想的には、stdoutとstderrには、画面上のさまざまな列など、別々の表示領域があります。たとえば、出力は次のようになります。

~$ some command
some useful output info
ERROR: an error
more output
ERROR: has occurred
another message
~$ 

代わりに次のようになります。

~$ some command          |
some useful output info  |
more output              |  ERROR: an error
another message          |  ERROR: has occurred
~$                       |

ベストアンサー1

screenGNUの垂直分割機能を使用できます。

#! /bin/bash -
tmpdir=$(mktemp -d) || exit
trap 'rm -rf "$tmpdir"' EXIT INT TERM HUP

FIFO=$tmpdir/FIFO
mkfifo "$FIFO" || exit

conf=$tmpdir/conf

cat > "$conf" << 'EOF' || exit
split -v
focus
screen -t stderr sh -c 'tty > "$FIFO"; read done < "$FIFO"'
focus
screen -t stdout sh -c 'read tty < "$FIFO"; eval "$CMD" 2> "$tty"; echo "[Command exited with status $?, press enter to exit]"; read prompt; echo done > "$FIFO"'
EOF

CMD="$*"
export FIFO CMD

screen -mc "$conf"

たとえば、次のように使用されます。

that-script 'ls / /not-here'

アイデアは、垂直に分割されたレイアウトで2つの画面ウィンドウを起動する一時的なconfファイルで画面を実行することです。最初のコマンドでは、コマンドを実行し、stderrを2番目のコマンドに接続します。

2番目のウィンドウの名前付きパイプを使用して最初のウィンドウとttyデバイスを通信し、最初のウィンドウはコマンドが完了すると2番目のウィンドウに通知します。

パイプベースのアプローチに比べてもう1つの利点は、コマンドのstdoutとstderrがまだttyデバイスに接続されているため、バッファリングに影響を与えないことです。どちらのウィンドウも独立して上下にスクロールできます(コピーscreenモードを使用)。

このスクリプトを使用してシェルを対話的に実行すると、プロンプトがbash2番目のウィンドウに表示され、最初のウィンドウに入力した内容がシェルによって読み取られます。なぜなら、このシェルはstderrにプロンプ​​トを出力するからです。

の場合bashエコ入力した内容が2番目のウィンドウにも表示されます。エコbashまた、シェルによってstderrに出力されます(この場合はreadline)。たとえば、他のシェルの場合は、最初のウィンドウksh93に表示されます(エコemacsシェルを使用したり、シェルをviモードに設定したりしない限り、シェルではなくターミナルデバイスドライバによって出力されます。set -o emacsset -o vi

おすすめ記事