在控制台中与上一个回显相同的位置打印某些内容,并带有负向回显


9

在bash中,您可以强制转换为clear清除所有屏幕命令的命令。

并且,echo您可以在屏幕上打印任何内容。

在我的简单脚本中,我经常需要打印命令执行的百分比。

所以我可以做类似的事情。

echo "89%"
echo "90%"
echo "91%"

等等..

我讨厌让屏幕充满百分比更新...

89%
90%
91%
...

我想了解的是是否有特殊的字符组合(例如“ \ 033 [01; 31m”),可以通过bash或php echo进行回显,并告诉控制台“删除上一个先前打印的字符。”

通过使用类似这样的方法:(php示例)

echo str_repeat($neg_character, strlen($last_percentage_update_string));
echo $new_percentage_update_string;

我将把新的字符串打印在上一个字符串的确切位置上,而无需在屏幕上充满一行

否则,我会寻找一种始终使用bash和php脚本以其他方式执行相同操作的方法(请至少使用debian9控制台和php7包括实际的工作示例)

Answers:


24

执行此操作的典型方法不是擦除单个字符,而是使用回车键(\r)返回到行首:

printf "89%%"; sleep 1; printf "\r90%%\n"

请注意,这并不能清除所有内容,因此如有必要,您需要注意这一点。简单的选择是在末尾添加空格,或使输出固定宽度(例如,printf "%2d%%\n" 1提供前导空格)。

有终端转义符,可以使您四处移动并清除屏幕的一部分CSI序列,但是它们取决于终端符(尽管实际上VT100逃生符现在在任何地方都受支持)。例如

printf "89%%"; sleep 1; printf "\e[3D90%%\n"

用于␛[3D将三个字符向左移动,并覆盖它们(假设您的printfsupport \e);

printf "89%% hello"; sleep 1; printf "\e[0E\e[K90%%\n"

用于␛[0E移至当前行的开头,并␛[K清除至行的末尾(假设您的终端支持这些序列)。

tput提供printf访问这些序列的终端和不可知方式:

printf "89%%"; sleep 1; tput cub 3; tput el; printf "90%%\n"

使用适合当前终端的任何字符序列将光标向左移动三次(cub 3),并清除到行的结尾(el);

printf "89%% hello"; sleep 1; tput hpa 0; tput el; printf "90%%\n"

会将光标移动到最左侧的列(hpa 0),并清除到该行的末尾。

man terminfo会告诉您使用什么“功能名称” tput

(请注意,上面示例的许多细节都假设您的所有输出都在同一行上。它们不应该是万无一失的,只是为了说明各种方法。)

对于PHP脚本中类似的屏幕控制,您可以查看PECL ncurses扩展。


5
人们通常可以使用tput cub 3移动立方米 rsor b由3列,而无需硬编码序列ACK(和tput elË RASE的 INE)。
斯特凡Chazelas

1. \e不是便携式的2.也不是\e[0E
史蒂文·彭妮

感谢@Steven,我提到序列是终端相关的,但是我添加了更多的限定词。
斯蒂芬·基特

一个可以ech用于擦除。向后移动3个位置有一个陷阱,全屏程序倾向于使用两种可能的优化方法。但是,当遵循一个建议使用固定宽度格式说明符时,对于仅用于当前线路的简单终端而言,优化和擦除都是过大的。100顺便说一句,不要忘记那是3位数字。(-:
JdeBP '18

好点@JdeBP,谢谢。一旦您达到100%,我肯定希望您不再需要进度更新;-)。
斯蒂芬·基特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.