Bash 选项使命令替换保留尾随换行符

Mel*_*lab 2 shell bash command-substitution

我希望它bash带有一个选项,可以阻止命令替换剥离尾随换行符。有没有?如果没有,那么是否存在类似的外壳bash,并且标准\xe2\x80\x94POSIX,我猜\xe2\x80\x94sh代码将在其中运行,它有这样的选项或者可能有一些特殊的语法对于不去除换行符的命令替换(后者更好)?

\n

Gor*_*son 5

没有选项可以直接执行此操作(据我所知),但您可以通过在命令替换中添加保护性非换行符来伪造它,然后将其删除:

var="$(somecommand; echo .)"  # Add a "." (and one newline that command
                              # substitution will remove) *after* the
                              # newline(s) we want to protect

var="${var%.}"  # Remove the "." from the end
Run Code Online (Sandbox Code Playgroud)

请注意, 的退出状态somecommand在进程中丢失,因为 和 都echo .设置var=${var%.}了状态(通常为 0)。如果你需要将其保存到最后,你需要添加一些杂耍(归功于 Kusalananda):

var="$(somecommand; err=$?; echo .; exit "$err")"  # Make the subshell
                                                   # exit with somecommand's
                                                   # status
commandstatus=$?    # Preserve the exit status of the subshell
var="${var%.}"
# You can now test $commandstatus to see if the command succeeded
Run Code Online (Sandbox Code Playgroud)

请注意,errcommandstatus变量都存储命令的退出状态,但它们不是多余的,因为err仅存在于 和 创建的子 shell 中$( ),并且commandstatus仅存在于父 shell 中。您可以对两者使用相同的名称,但这可能会增加混乱。

顺便说一句,如果您不需要在“.”之后保留状态。已修剪,可以跳过该commandstatus部分:

if var="$(somecommand; err=$?; echo .; exit "$err")"; then
    # somecommand succeeded; proceed with processing
    var="${var%.}"
    dosomethingwith "$var"
else
    echo "somecommand failed with exit status $?" >&2
fi
Run Code Online (Sandbox Code Playgroud) 请注意,根据区域设置,您不能仅使用任何字符来代替“.”。POSIX 保证不会在其他字符的编码中找到“.”的编码,但并非所有情况都是如此。例如,在实践中,“x”的编码位于 BIG5 或 GB18030 编码中许多字符的编码末尾,因此如果附加“x”而不是“.”,则“x”可能会结束up 与恰好出现在输出末尾的另一个字节组合形成一个新字符,然后“${var%x}”将无法删除该“x”。