您可以使用GNU screen
的垂直拆分功能:
#! /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'
这个想法是它运行带有临时conf文件的屏幕,该文件在垂直拆分布局中启动两个屏幕窗口。在第一个命令中,我们将stderr连接到第二个命令来运行您的命令。
我们在第二个窗口中使用命名管道将其tty设备与第一个窗口进行通信,并且在第一个窗口将命令完成时告知第二个窗口。
与基于管道的方法相比,另一个优点是命令的stdout和stderr仍连接到tty设备,因此它不会影响缓冲。两个窗格也可以独立地上下滚动(使用screen
的复制模式)。
如果您bash
使用该脚本以交互方式运行shell ,您会注意到提示将显示在第二个窗口中,而该shell将读取您在第一个窗口中键入的内容,因为这些shell在stderr上输出其提示。
对于bash
,您键入的回显也将出现在第二个窗口中,因为该回显也是由bash
stderr上的shell输出的(对于则为readline )。对于其他类似的Shell ksh93
,它将显示在第一个窗口中(由终端设备驱动程序而不是Shell输出回显),除非您将Shell置于emacs
或vi
模式下set -o emacs
或set -o vi
。