处理特定长度的 bash 中断命令

处理特定长度的 bash 中断命令

考虑一下您想要在以下位置运行此命令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命令会打开“突出模式” - 这应该会使内容%更加突出 - 可能是粗体,也可能是通过反转背景和前景色来实现的。

相关内容