用字符串调用bash函数

时间:2015-04-23 16:43:33

标签: bash shell

我有一个bash函数:

function some_function()
{
   $*
}

我这样称呼这个函数:

some_function "cal 2014"

为什么我会得到一个" cal 2014":找不到错误?

但如果我打电话,它就有用了:

some_function "cal"

2 个答案:

答案 0 :(得分:2)

让我们在这里检查各种行为一分钟。

$ # Helper function to show some useful details.
$ c ()
{
    printf 'argc: %s\n' "$#";
    printf 'argv: %s\n' "$@"
}
$ # The function in question.
$ t ()
{
    printf '$*\n';
    c $*;
    $*;
    printf '"$*"\n';
    c "$*";
    "$*";
    printf '$@\n';
    c $@;
    $@;
    printf '"$@"\n';
    c "$@";
    "$@"
}

如果我们调用此函数t "echo foo",我们就会得到

$*
argc: 2
argv: echo
argv: foo
foo
"$*"
argc: 1
argv: echo foo
-bash: echo foo: command not found
$@
argc: 2
argv: echo
argv: foo
foo
"$@"
argc: 1
argv: echo foo
-bash: echo foo: command not found
  • $*$@版本扩展为两个参数并正常工作。
  • "$*""$@"版本扩展为单个参数并失败。

如果我们将其称为t echo foo

,该怎么办?
$*
argc: 2
argv: echo
argv: foo
foo
"$*"
argc: 1
argv: echo foo
-bash: echo foo: command not found
$@
argc: 2
argv: echo
argv: foo
foo
"$@"
argc: 2
argv: echo
argv: foo
foo
  • 这次$*$@"$@"版本都扩展为两个参数并且有效。
  • 只有"$*"版本扩展为单个参数并失败。

确定。这是有道理的,因为$*将参数扩展为单独的(未引用的)单词; "$*"扩展为单个(引用)字词; $@扩展为$*;并且"$@"扩展为单个(引用)单词。

如果我们试试t echo "foo bar"怎么办?

$*
argc: 3
argv: echo
argv: foo
argv: bar
foo bar
"$*"
argc: 1
argv: echo foo bar
-bash: echo foo bar: command not found
$@
argc: 3
argv: echo
argv: foo
argv: bar
foo bar
"$@"
argc: 2
argv: echo
argv: foo bar
foo bar

现在事情变得有趣了。

  • $*扩展为三个参数。 (好的。之前我确实说过“个别(不带引号)的话)”。
  • "$*"扩展为一个参数。 (右,“单(引用)字”。)
  • $@扩展为三个参数。 (右,与$*相同。)
  • "$@"扩展为两个参数并正确保留内部空间。 (正如我所说的“个别(引用)的话)”。)

这就是为什么一般来说,你总是引用变量,而且几乎总是希望在@扩展上使用*扩展。因为它们正确处理空格和元字符。

最终虽然我们直接使用$*时没有重现您的问题。您确定没有使用"$*"吗?

答案 1 :(得分:0)

如果你这样引用"cal 2014",你就把它变成了一个参数。您可能需要some_function "cal" "2014",看看它是否适合您。也就是说,我无法重现您描述的错误。