命令替换删除每个尾随换行符。
删除一个是有意义的。例如:
basename foo/bar
输出bar\n
。在:
var=$(basename foo/bar)
你想$var
包容bar
,不是bar\n
。
然而在
var=$(basename $'foo/bar\n')
您想$var
包含bar\n
(毕竟,换行符与 Unix 上的文件名中的任何字符一样有效)。但是所有的 shell 都会删除每个尾随的换行符。这个错误出现在最初的 Bourne shell 中,即使rc
修复了 Bourne 的大部分缺陷,也没有修复那个缺陷。(尽管rc
有``(){cmd}
不删除任何换行符的语法)。
在 POSIX shell 中,要解决此问题,您可以执行以下操作:
var=$(basename -- "$file"; echo .)
var=${var%??}
尽管您随后失去了basename
. 您可以使用以下方法修复:
var=$(basename -- "$file" && echo .) && var=${var%??}
${var%??}
就是去掉最后两个字符。第一个是.
我们在上面添加的,第二个是由 添加的一个换行符basename
,我们不再删除,因为命令替换会像其他换行符(如果有的话)将成为我们想要的文件名的一部分得到基地,所以我们确实想要他们。
在没有${var%x}
操作符的 Bourne shell 中,您必须采取漫长而复杂的方式来解决它。