处理一定长度的bash破坏命令

考虑你想在bash运行这个命令:

 echo -n "Command of a specific length will break at the second run attempt." 

这是24×80 TTY的输出:

 ubuntu@ubuntu:~$ echo -n "Command of a specific length will break at the second run attempt." Command of a specific lenght will break at the second run attempt.ubuntu@ubuntu: ~$ 

考虑您想再次运行相同的命令。

一击到

 ubuntu@ubuntu:~$ echo -n "Command of a specific lenght will break at the second run attempt." Command of a specific lenght will break at the second run attempt.ubuntu@ubuntu: run attempt."ommand of a specific lenght will break at the second r 

这种情况发生在一定大小的命令中,不会在最后打印换行符。

这非常烦人。 到目前为止,我还没有找到任何解决方案,我认为每个遇到这个问题的人都会非常感谢那些有解决方案的人。

这也可以用bash来完成。 诀窍是使用自定义PROMPT_COMMAND来查询终端的光标位置(根据这个问题 )。

这个解决方案可能会扩展到其他shell,但我只熟悉bash 。 (参见@muru对zsh解决方案的回答)。 也许bash已经有一个选项可以自动执行此操作。

把它放在你的.bashrc

 function new.line.if.not.on.left { local foo local garbage local column echo -n -e "\033[6n" # as the terminal for the position read -s -d \[ garbage # ignore the first part of the response read -s -d R foo # store the position in foo column="$(echo "$foo" | cut -d';' -f2)" # skip over the row number test "$column" "!=" 1 && { tput smso; echo "%"; tput rmso; } } PROMPT_COMMAND="new.line.if.not.on.left; $PROMPT_COMMAND" 

最后一行new.line.if.not.on.left调用new.line.if.not.on.left到您的PROMPT_COMMAND (因为您可能已经定义了PROMPT_COMMAND )。

bash函数new.line.if.not.on.left工作原理如下:

  • echo -n -e "\033[6n"是一个魔术,它向终端询问光标当前位置的行和列。 终端通过发送带有答案的假键盘输入来“响应”。
  • read -s -d \[ garbage 。 响应的第一部分是一些乱码,某种逃脱代码。 通过将其存储在garbage忽略它。
  • read -s -d R foo 。 将假键盘响应存储在bash变量foo-s需要停止read再次回显屏幕输入。 并且-d R是分隔符 – 假输入由R终止,而不是像您期望的那样通过换行符终止。
  • column="$(echo "$foo" | cut -d';' -f2)"从响应中提取列号(即跳过行号)并将结果存储在column
  • test "$column" "!=" 1 && { tput smso; echo "%"; tput rmso; } 如果当前列号不是1,则打印百分号(和换行符)。 tput命令打开“ tput模式” – 这应该使%更突出 – 可能是粗体或者可能通过反转背景和前景色。

使用更聪明的shell,比如zsh

在此处输入图像描述

请注意它是如何添加%来表示缺少换行符并在另一行上打印提示符。

只需按Ctrl L即可 。 这将重绘您的终端并使所有内容显示为应该:

在此处输入图像描述