Zoe*_*wll 18 command-line terminal
我正在寻找一种在视觉上分离 stdout 和 stderr 的方法,这样它们就不会交错,从而可以轻松识别它们。理想情况下,stdout 和stderr 在显示它们的屏幕上会有不同的区域,例如在不同的列中。例如,输出看起来像这样:
~$ some command
some useful output info
ERROR: an error
more output
ERROR: has occurred
another message
~$
Run Code Online (Sandbox Code Playgroud)
而是看起来像这样:
~$ some command |
some useful output info |
more output | ERROR: an error
another message | ERROR: has occurred
~$ |
Run Code Online (Sandbox Code Playgroud)
您可以使用 GNUscreen
的垂直拆分功能:
#! /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"
Run Code Online (Sandbox Code Playgroud)
例如用作:
that-script 'ls / /not-here'
Run Code Online (Sandbox Code Playgroud)
这个想法是它使用临时 conf 文件运行 screen ,该文件以垂直拆分布局启动两个屏幕窗口。在第一个中,我们使用连接到第二个的 stderr 运行您的命令。
我们为第二个窗口使用命名管道将其 tty 设备与第一个窗口通信,并在命令完成后第一个窗口通知第二个窗口。
与基于管道的方法相比,另一个优点是命令的 stdout 和 stderr 仍然连接到 tty 设备,因此它不会影响缓冲。两个窗格也可以独立上下滚动(使用screen
的复制模式)。
如果您bash
使用该脚本以交互方式运行 shell ,您会注意到提示将显示在第二个窗口中,而 shell 将读取您在第一个窗口中键入的内容,因为这些 shell 在 stderr 上输出它们的提示。
在 的情况下bash
,您键入的内容的回声也将出现在第二个窗口中,因为该回声也是由 shell(在 的情况下为 readline bash
)在 stderr 上输出的。对于其他一些 shell,如ksh93
,它将显示在第一个窗口上(终端设备驱动程序的回显输出,而不是 shell),除非您将 shell 置于emacs
orvi
模式下set -o emacs
或set -o vi
。