我该如何处理需要引用的参数的函数调用?
例如,考虑以下函数
time-stamp ()
{
if (( $# == 0)); then
tmstamp="$(date +T%T.%N)"
else
tmstamp="$(date $1)"
fi
echo "$tmstamp"
}
以下是一些可能的调用方式
var="+%T %N"
stamp=$( date "${var}" )
或者
var="+%T %N"
stamp="$( date "${var}" )"
答案1
这个结构$(some_commands ...)
称为命令替换。
两个示例之间的区别在于对命令替换结果的处理,而不是命令的参数。(注意:您也可以将 shell 函数或别名放在命令的位置。)
Shell 替换结果处理
Shell 对命令替换的结果执行单词/字段拆分和文件名扩展。如果要阻止这些更改,请将构造括在双引号中,就像在第二个示例中所做的那样:
var="+%T %N"
stamp="$( date "${var}" )"
如果不这样做,shell 会用空格分隔符将结果拆分为单词/字段和/或对通配符(如*
, ?
, )执行文件名扩展[]
。除非您希望 shell 进行修改,否则应该在那里使用双引号。
例外与示范
赋值是一个例外。POSIX shell(包括 bash)不会对变量赋值执行单词拆分和文件名扩展:1
$ printf '<%s>' $(echo 'a b') ; echo
<a><b>
$ x=$(echo 'a b')
$ printf '<%s>' "$x" ; echo
<a b>
$ touch file1 file2
$ printf '<%s>' $(echo '*') ; echo
<file1><file2>
$ x=$(echo '*')
$ printf '<%s>' "$x" ; echo
<*>
请注意,在第一个示例中,变量x
确实包含完整的字符串a b
(包括四个空格),因此它在赋值时没有被拆分。在这种情况下使用引号不会改变结果,但您可以使用它们来保持良好的习惯。