我的命令替换中的尾随换行符哪里去了?

我的命令替换中的尾随换行符哪里去了?

下面的代码最好地描述了这种情况。为什么最后一行不输出尾随换行符?每行的输出都显示在注释中。我在用着GNU bash,版本 4.1.5

     echo -n $'a\nb\n'                  | xxd -p  # 610a620a  
           x=$'a\nb\n'   ; echo -n "$x" | xxd -p  # 610a620a
     echo -ne "a\nb\n"                  | xxd -p  # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p  # 610a62

答案1

命令替换函数$()(及其近亲反引号)专门删除尾随换行符。这是记录的行为,并且在使用该构造时应该始终注意它。

文本主体内的换行符不会被替换运算符删除,但在 shell 上进行分词时也可能会被删除,因此结果取决于您是否使用了引号。请注意这两种用法之间的区别:

$ echo -n "$(echo -n 'a\nb')"
a
b

$ !! | xxd -p
610a62

$ echo -n  $(echo -n 'a\nb')
a b

$ !! | xxd -p   
612062

在第二个示例中,输出没有被引用,换行符被解释为分词,使其在输出中显示为空格!

答案2

使用命令替换时,shell 在子 shell 中执行命令,返回其标准输出。在此过程中,IFS 字符失去了它们的意义(如果它们没有被引用),因为命令返回简单的分割词,因此尾随的字符被删除。例如:

$ echo "$(echo -e '\n')" | wc
 1       0       1

$ echo -e '\n' | wc
2       0       2

更实际的是,pwd即使您的目录名称之间有换行符,也会起作用,但$(pwd)不会。

通常的解决方法是在命令末尾添加一些内容,然后删除它。

相关内容