我可以在命令行覆盖多行标准输出而不丢失终端回滚吗?

我可以在命令行覆盖多行标准输出而不丢失终端回滚吗?

我想创建多个进度条并随时更新它们,而不需要清除整个屏幕(我希望以前的标准输出内容保留在屏幕上)。

我需要:

  1. 写几行echo
  2. 等待与sleep
  3. 让我的光标回到第一行的开头
  4. 用更新的信息覆盖我的几行
  5. 从步骤 2 开始重复。

我的想法是我希望用户能够向后滚动以阅读以前的标准输出内容。

如果我不关心回滚,我只需使用clear并再次写出我需要的内容:

while [ true ]; do echo "$SECONDS"; sleep 0.1; clear; done

然而,这使得回滚完全不可读,因为clear只是打印出足够的换行符以将先前的终端输出推到视图之外。

当我运行htop并关闭它时 - 它将我的终端恢复到与启动 htop 时完全相同的状态。这样的事情可以在 bash 脚本中实现吗?

答案1

使用tput sc tput edtput rc.

输入手册

tput sc

保存光标位置

tput rc

恢复光标位置

tput ed

清除到屏幕末尾

例子:

tput sc
while :; do
    tput ed
    echo -e "$SECONDS\n$SECONDS\n$SECONDS"
    sleep 1
    tput rc
done

它是如何工作的?

  1. 存储光标位置tput sc
  2. 进入将更新屏幕上信息的循环
  3. tput ed清除到屏幕末尾以确保正确的结果
  4. 然后多行变化的数据被写入echo
  5. sleep 1刷新前等待一秒钟
  6. tput rc将光标移回到我们刚刚打印的行的开头
  7. 循环重复用新信息覆盖

答案2

您可以将tput cuu1光标向上移动一行(或者无论您需要向上移动多少行才能覆盖),然后覆盖。

例如:

echo -e "foo\nbar"
tput cuu1
tput cuu1
echo -e "baz\nquux"

产量:

baz
quux

相关内容