编辑:已更正的进程/线程术语
我的Shell脚本具有一个前台进程,该进程读取用户输入,而后台进程则打印消息。我想将这些消息打印在输入提示上方的行上,而不是中断输入。这是一个罐头示例:
sleep 5 && echo -e "\nINFO: Helpful Status Update!" &
echo -n "> "
read input
当我执行它并多次输入“输入”时,我得到的东西是这样的:
> input input input inp
INFO: Helpful Status Update!
ut input
但是我想看到这样的东西:
INFO: Helpful Status Update!
> input input input input input
该解决方案不必是可移植的(我正在linux上使用bash),尽管我想尽可能避免ncurses。
编辑:根据@Nick的说法,由于历史原因,无法访问前几行。但是,我的情况仅需要修改当前行。这是概念证明:
# Make named pipe
mkfifo pipe
# Spawn background process
while true; do
sleep 2
echo -en "\033[1K\rINFO: Helpful Status Update!\n> `cat pipe`"
done &
# Start foreground user input
echo -n "> "
pid=-1
collected=""
IFS=""
while true; do
read -n 1 c
collected="$collected$c"
# Named pipes block writes, so must do background process
echo -n "$collected" >> pipe &
# Kill last loop's (potentially) still-blocking pipe write
if kill -0 $pid &> /dev/null; then
kill $pid &> /dev/null
fi
pid=$!
done
这基本上会产生 正确的行为,但缺少诸如退格键和箭头导航之类的CLI优点。这些可能会被入侵,但是我仍然很难相信还没有开发出一种标准方法。
答案 0 :(得分:1)
原始ANSI代码仍然可以在Linux(和MacOS)的bash终端中使用,因此可以使用\ 033 [F,其中\ 033是ESCape字符。您可以通过bash终端中的control-V和ESCape字符来生成它。您应该看到^[
出现。然后键入[F
。如果您测试以下脚本:
echo "original line 1"
echo "^[[Fupdated line 1"
echo "line 2"
echo "line 3"
您应该看到输出:
updated line 1
line 2
line 3
编辑:
我忘了补充一点,在脚本中使用它会导致光标返回到该行的开头,因此进一步的输入将覆盖您已经键入的内容。您可以在键盘上使用control-R来使bash重新键入当前行并将光标返回到该行的末尾。