bash - 在 bash 中打印到终端输出上方的行
问题描述
编辑:更正进程/线程术语
我的 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 细节,如退格和箭头导航。这些可能会被黑客入侵,但我仍然无法相信尚未开发出标准方法。
解决方案
原始 ANSI 代码在 Linux(和 MacOS)上的 bash 终端中仍然有效,因此您可以使用 \033[F 其中 \033 是 ESCape 字符。您可以通过 control-V 后跟 ESCape 字符在 bash 终端中生成它。你应该看到^[
出现。然后键入[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 重新键入当前行并将光标返回到行尾。
推荐阅读
- c++ - 为什么当我运行一个计数为 5368709120 和几行 memcpy 的 for 循环时性能会大大降低?
- ios - iOS 上的 Google MLKit 对象检测问题
- flipkart-api - 如何使用卖家列表 API 在 Flipkart 中创建产品?
- c - 如何修复“将'bool'传递给'bool(*)[9]'类型参数的不兼容整数到指针转换”?C
- c++ - 在函数中使用 struct std::map
- c# - 如何获取 customPairing.PairAsync 的实际失败原因?
- javascript - 我的代码 javascript 中的某些内容无法制作三角形
- javascript - 在拆分数组中查找元素位置
- flutter - Dart:变量名后面的问号 (?) 是什么意思?
- java - Print 4 numbers (that are divisible by 3 and 6) before x and store them in an array