我正在自定义 zshPROMPT
并调用一个函数,该函数可能是也可能不是echo
基于环境变量状态的字符串:
function my_info {
[[ -n "$ENV_VAR"]] && echo "Some useful information\n"
}
local my_info='$(my_info)'
PROMPT="${my_info}My awesome prompt $>"
我希望信息以尾随换行符结尾,这样如果设置了它,它就会显示在自己的行上:
Some useful information
My awesome prompt $>
但是,如果未设置,我希望提示符位于单行上,避免提示符中的无条件换行符导致出现空行:
PROMPT="${my_info} # <= Don't want that :)
My awesome prompt $>"
目前,我$(command substitution)
通过在换行符后添加非打印字符来解决删除换行符的问题,因此换行符不再尾随:
[[ -n "$ENV_VAR"]] && echo "Some useful information\n\r"
这显然是一个黑客行为。有没有一种干净的方法来返回以换行符结尾的字符串?
编辑:我明白是什么导致尾随换行符丢失和为什么会发生这种情况,但在这个问题中我特别想知道如何防止这种行为(而且我不认为这个解决方法适用于我的情况,因为我正在寻找“条件”换行符)。
编辑:我纠正一下:参考解决方法实际上可能是一个相当不错的解决方案(因为在比较中添加前缀字符串是一种常见且有些相似的模式),但我无法让它正常工作:
echo "Some useful information\n"x
[...]
PROMPT="${my_info%x}My awesome prompt $>"
不会x
为我删除尾随。
编辑:调整建议的解决方法以解决快速扩展的怪异问题,这对我有用:
function my_info {
[[ -n "$ENV_VAR"]] && echo "Some useful information\n"x
}
local my_info='${$(my_info)%x}'
PROMPT="$my_info My awesome prompt $>"
您可以判断这是否是比原始解决方案更好的解决方案。我认为它更明确一点,但也感觉可读性较差。
答案1
最后的换行符从命令替换中删除。即使 zsh 也没有提供避免这种情况的选项。因此,如果您想保留最终换行符,则需要将它们安排为不是最终换行符。
最简单的方法是在您想要准确获取的数据后面打印一个额外的字符(换行符除外),并从命令替换的结果中删除最后一个额外的字符。您可以选择在该额外字符后添加换行符,无论如何它都会被删除。
在 zsh 中,您可以将命令替换与字符串操作结合起来以删除多余的字符。
my_info='${$(my_info; echo .)%.}'
PROMPT="${my_info}My awesome prompt $>"
在您的场景中,请注意这my_info
不是命令的输出,而是用于获取输出的 shell 片段,当提示符展开时将对其进行评估。PROMPT=${my_info%x}…
不起作用,因为它尝试x
从变量的值中删除最终值my_info
,但它以)
.
在其他 shell 中,这需要分两步完成:
output=$(my_info; echo .)
output=${output%.}
在 bash 中,您不能my_info
直接从调用PS1
;而是需要从 调用它PROMPT_COMMAND
。
PROMPT_COMMAND='my_info=$(my_info; echo .)'
PS1='${my_info%.}…'
答案2
您可以让函数输出转义的转义码,以便在展开时它变成换行符。
$ function my_info {
> [[ -n "$ENV_VAR"]] && echo 'Some useful information\\n'
>}
$ echo $(my_info)
Some useful information
$