Bash:如何知道最后一个命令的输出是否以换行符结束?

Bash:如何知道最后一个命令的输出是否以换行符结束?

大多数情况下,命令的输出以换行符结束。但有时并非如此,因此下一个 shell 提示符将与输出一起打印在同一行中。

例子:

root@主机名 [~] # echo -n hello
helloroot@主机名 [~] #

我一直觉得这很烦人。
现在,我可以在 PS1 变量的开头添加一个“\n”,但大多数情况下,这会打印一行我不需要的额外内容。

是否有可能知道最后一个命令的输出是否以换行符结束?


解决方案:
(感谢丹尼斯)

PS1='$(printf "%$((`tput cols`-1))s\r")\u@\h [\w]\$ '

答案1

zsh我一直在尝试以下方法来模拟Bash 中的功能:

$ unset PROMPT_SP; for ((i = 1; i <= $COLUMNS + 52; i++ )); do PROMPT_SP+=' '; done
$ PS1='\[\e[7m%\e[m\]${PROMPT_SP: -$COLUMNS+1}\015$ '

它会发出一个反向视频百分号,后面跟着一堆空格,使其换行到下一行,然后是一个回车符,后面跟着一个美元符号和一个空格。您可以在“\015”后添加提示转义符来自定义您的提示。

使用此选项取决于您的终端如何处理右侧边距换行(自动边距)。 PROMPT_SP 的长度是任意的,但应至少为 80 或您通常的终端宽度。 如果在 中for运行循环时尚未设置 $COLUMNS,则可能需要对该值进行硬编码。 如果尚未设置,~/.bashrc您可能需要。shopt -s checkwinsize

答案2

zsh尝试解决您的问题。如果最后的输出没有换行符,您将得到:

$ echo -n 'abc'
abc%
$ 

使用反转背景/前景的地方%。不确定它是否可以bash以任何方式移植。

答案3

不,这是不可能的。Bash 本身不会处理或查看它启动的程序的输出。

我突然想到可能可以编写一个程序来设置PROMPT_COMMAND,该程序将检查光标的当前位置,如果光标不在左边缘,则发出换行符。

答案4

我从@Teddy 那里得到了这个想法,即检测水平光标的位置,如果它不在第一列,则发出换行符。

在 bash 中,我们可以使用此命令检测光标位置:IFS=';' read -sdR -p $'\E[6n' ROW COL。更多信息请参阅此答案:https://unix.stackexchange.com/a/183121/340297
COL变量保存光标所在的当前列。如果$COL不等于 1,则在设置 PS1 变量之前添加换行符。

这是我的实现:

_set_prompt() {
    IFS=';' read -sdR -p $'\E[6n' ROW COL # Get cursor position
    [ $COL -ne 1 ] && echo '' # Add newline if cursor is not at 1st column
    PS1="........." # Your PS1 variable
}

PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND; }'_set_prompt'

结果如下(PS1 不同):
在此处输入图片描述

echo -n不包括换行符,但在显示提示符之前会发出换行符。而如果换行符已由常规 echo 命令打印,则不会出现额外的换行符。

相关内容