考虑一下您想要在以下位置运行此命令bash
:
echo -n "Command of a specific length will break at the second run attempt."
以下是 24x80 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
当命令达到一定大小且末尾不打印换行符时,就会发生这种情况。
这非常烦人。到目前为止,我还没有找到任何解决办法,我认为每个遇到这个问题的人都会真的感谢能解决这个问题的人。
答案1
使用更智能的外壳,例如zsh
:
请注意它是如何添加的%
以指示缺少换行符并在不同的行上打印提示。
答案2
只要点击CtrlL。这将重新绘制你的终端并使所有内容按应有的方式显示:
答案3
也可以使用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
对您的调用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
命令会打开“突出模式” - 这应该会使内容%
更加突出 - 可能是粗体,也可能是通过反转背景和前景色来实现的。