假设你希望你的提示符看起来像这样:
left text----------------------------------------------------------right text
prompt$
如果right text
的大小是已知的,这个过程就比较简单了。(例如,它可能是当前的日期和时间。)我们需要做的是打印出正确数量的短横线(或者对于utf-8终端,更漂亮的\u2500
),接着是right text
,然后是一个回车符(\r
,而不是换行符),最后是左侧的文本,它将覆盖掉短横线。唯一棘手的部分是“正确数量的短横线”,但是我们可以使用$(tput cols)
来查看终端的宽度,幸运的是,bash
将会展开PS1
。因此,例如:
PS1='\[$(printf "%*s" $(($(tput cols)-20)) "" | sed "s/ /-/g") \d \t\r\u@\h:\w \]\n\$ '
这里的
$(($(tput cols)-20))
是终端宽度减去20,这基于
\d \t
恰好为20个字符宽(包括初始空格)。
PS1
无法理解utf-8转义符号(
\uxxxx
),将相应替换插入到
sed
命令中涉及麻烦的嵌套引号问题,虽然有可能。但是,
printf
能够理解utf-8转义符号,因此更容易以不同的方式生成破折号序列:
PS1='\[$(printf "\\u2500%.0s" $(seq 21 $(tput cols))) \d \t\r\u@\h:\w \]\n\$ '
另一种方法是关闭终端的自动换行功能,如果您使用的是xterm或实现了相同控制代码的终端模拟器(或Linux控制台本身),则可能实现此功能。要禁用自动换行,请输出序列
ESC[?7l。要重新启用,请使用
ESC[?7h。当自动换行被禁用时,一旦输出达到一行的末尾,最后一个字符将只是被下一个字符覆盖而不是开始一个新行。使用这种技术,不需要计算破折号序列的确切长度; 我们只需要一个比任何控制台都宽的破折号字符串,例如以下内容:
DASHES="$(printf '\u2500%0.s' {1..1000})"
PS1='\[\e[?7l\u@\h:\w $DASHES \e[19D \d \t\e[?7h\]\n\$ '
这里,
\e[19D
是“将光标向后移动19个字符”的终端仿真器代码。我也可以使用
$(tput cub 19)
。 (可能有一个
tput
参数用于打开和关闭自动换行,但我不知道它是什么。)
视频中的示例还涉及在实际命令行中插入右对齐字符串。我不知道使用
bash
有任何干净的方法; 视频中的控制台几乎肯定使用了带有
RPROMPT
功能的
zsh
。当然,您可以使用与上面相同的技术在
bash
中输出右对齐提示,但是
readline
不会知道它们的存在,因此一旦您执行某些操作来编辑该行,右提示将消失。