![保存后恢复光标位置](https://linux22.com/image/166955/%E4%BF%9D%E5%AD%98%E5%90%8E%E6%81%A2%E5%A4%8D%E5%85%89%E6%A0%87%E4%BD%8D%E7%BD%AE.png)
保存和恢复光标位置应该可以通过简单的ANSI 转义序列
ANSI 转义序列允许您在屏幕上随意移动光标。这对于 shell 脚本生成的全屏用户界面更有用,但也可以在提示中使用。运动转义序列如下:
- [...]
- 保存光标位置:
\033[s
- 恢复光标位置:
\033[u
然而,这个 ANSI 序列似乎只恢复光标的水平位置。例如:
$ printf 'Doing some task...\e[s\n\nMore text\n\e[udone!\n\n\n'
Doing some task...
More text
done!
$
其中 水平done!
位于正确位置,但垂直方向不正确(在恢复的意义上是正确的)。
- 我错过了什么吗?你能重现这个吗?!
- 这是预期的行为吗?如果是这样,我将如何
done!
在之后打印task...
? - 如果这种情况不应该发生,那么这种行为可能是由我的环境中的某些东西间接触发的吗?
我搜索并阅读了许多问题,但我没有找到任何关于我经历过的这种行为的信息。实际上, tput
via也会发生同样的情况
$ printf 'Doing some task...'; tput sc; printf '\n\nMore text\n'; tput rc; printf 'done!\n\n\n'
答案1
我错过了什么吗?你能重现这个吗?!
如果我位于终端底部并且下一行使内容向上移动,我可以。但在终端中重复测试不滚动同时。点击Ctrl+ L(或调用clear
)并从顶部开始。然后它的行为就会如你所愿。
这是预期的行为吗?
我想是这样。光标位置是相对于屏幕的,而不是相对于屏幕内容的。
done!
之后如何打印task...
?
可能的方法:如果您知道要打印不超过 6 行并且终端足够大,请先打印 6 个空行,以便它先滚动,然后向上移动光标,然后才打印有意义的文本:
printf '\n\n\n\n\n\n'; printf '\033[6A'; printf 'Doing some task...\e[s\n\nMore text\n\e[udone!\n\n\n'
我使用了三个单独的printf
s 来展示逻辑,但也可以是一个。
答案2
对我有用。我更喜欢使用术语信息数据库( man 5 terminfo
) 而不是硬编码转义序列。
sc=$(tput sc) rc=$(tput rc) el=$(tput el)
clear; printf 'Doing some task...%s\n' "$sc"; sleep 1; printf '%sDONE%s\n' "$rc" "$el"
您还可以将光标移动到绝对位置({0,0} 位于左上角),以防这是比保存/恢复当前光标位置更好的选择。
tput cup 4 40; sleep 1; printf "%s\n" 'This is row 4 column 40'