在bash中打印到终端输出上方的行
编辑:更正了进程/线程术语 我的shell脚本有一个读取用户输入的前台进程和一个打印消息的后台进程。我希望在输入提示上方的行上打印这些消息,而不是中断输入。下面是一个固定的例子:在bash中打印到终端输出上方的行,bash,terminal,Bash,Terminal,编辑:更正了进程/线程术语 我的shell脚本有一个读取用户输入的前台进程和一个打印消息的后台进程。我希望在输入提示上方的行上打印这些消息,而不是中断输入。下面是一个固定的例子: sleep 5 && echo -e "\nINFO: Helpful Status Update!" & echo -n "> " read input 当我执行它并多次输入“input”时,我得到如下结果: > input input input inp INFO: Helpf
sleep 5 && echo -e "\nINFO: Helpful Status Update!" &
echo -n "> "
read input
当我执行它并多次输入“input”时,我得到如下结果:
> input input input inp
INFO: Helpful Status Update!
ut input
INFO: Helpful Status Update!
> input input input input 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细节。这些代码可能会被入侵,但我仍然难以相信标准方法尚未开发出来。原始的ANSI代码仍然在Linux(和MacOS)上的bash终端中工作,因此您可以使用\033[F,其中\033是转义字符。您可以在bash终端中通过control-V后跟转义字符生成此字符。您应该看到出现
^[
。然后键入[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重新键入当前行并将光标返回到行尾。这些是“进程”,而不是“线程”。我认为这里没有避免诅咒的方法。为什么要避免使用事实上的标准工具进行光标寻址,还有什么(可移植的!)你希望用什么机制来取代它?多线程应用于单个进程中的线程。shell脚本不是多线程的。shell处理多个进程,而不是线程。我想避免诅咒,因为这看起来应该很简单。我不需要编辑前几行,只需要编辑当前一行。例如,如果我想使用更难的是,我可以一个字符一个字符地读取输入,然后当状态更新发生时,我覆盖整行并将已经输入的文本打印到新的行上。但这似乎已经是一件事情了。这是一种非常有希望的方法,我不知道转义序列。有没有办法在doi的时候跳过当前行这样的话,如果我打印了多行的状态更新,提示将继续在屏幕上被按下。另外,control-R是否有一个响应的转义序列,这样它就可以自动执行?这个问题已经把我带到了记忆通道上!颠簸:我认为没有(请记住,这些代码是从纸质终端时代开始的,所以您无法实际执行!)Control-R仅限于键盘。有两种代码“应该”执行将光标返回到输入行末尾的操作:SCP和RCP(请参阅)。当您发送消息时,我正在尝试它们,但它们似乎已被禁用/未激活。