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

Pet*_*r.O 15 command-line shell text-processing command-substitution

下面的代码最好地描述了这种情况。为什么最后一行不输出尾随换行符?每行的输出都显示在注释中。我使用的是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
Run Code Online (Sandbox Code Playgroud)

Cal*_*leb 18

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

替换操作符不会删除文本正文中的换行符,但是在 shell 上进行分词时它们也可能会被删除,因此结果如何取决于您是否使用了引号。注意这两种用法的区别:

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

$ !! | xxd -p
610a62

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

$ !! | xxd -p   
612062
Run Code Online (Sandbox Code Playgroud)

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


Phi*_*ath 6

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

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

$ echo -e '\n' | wc
2       0       2
Run Code Online (Sandbox Code Playgroud)

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

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