调用带有必须用引号括起来的参数的 bash 函数

调用带有必须用引号括起来的参数的 bash 函数

我该如何处理需要引用的参数的函数调用?

例如,考虑以下函数

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(包括四个空格),因此它在赋值时没有被拆分。在这种情况下使用引号不会改变结果,但您可以使用它们来保持良好的习惯。

相关内容