处理一定长度的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即可 。 这将重绘您的终端并使所有内容显示为应该: