将“$@”放入破折号的局部变量中

将“$@”放入破折号的局部变量中

我有一个 Bash 函数,它通过将其放入局部变量中来对整个参数进行一些字符串操作 ( "$@"),如下所示:

my_func() {
    local args="$@"
    echo "args: <$args>"
}

my_func "$@"

当我在 Bash 中运行它时,args包含传递的所有参数:

$ bash foo.sh foo bar baz
args: <foo bar baz>

但是,如果我在 Dash 中运行它,则仅存储第一个参数:

$ dash test.sh foo bar baz
args: <foo>

阅读localUbuntu Wiki 的“Dash as /bin/sh”页面中的部分,看起来 Dash 正在local args="$@"像这样扩展产品线:

local args=foo bar baz

因此只将“foo”放入并将和args声明为(本地?)变量。事实上,如果我在参数中添加并运行它,它似乎确认我正在添加变量:barbazecho "bar: $bar"my_func=

$ foo.sh foo bar=baz
args: <foo>
bar: baz

说了这么多,有没有办法$args在 Dash 中获得类似 Bash 的行为(包含“foo bar baz”)?

答案1

的扩张$@local args="$@" 未指定通过 POSIX 标准。 shellbash将创建一个以空格分隔的字符串,其中包含所有位置参数作为变量的值args,同时dash将尝试执行local args="$1" "$2" "$3"(等等)

和shell 的行为类似于(从位置参数中创建单个字符串,尽管会使用第一个字符 来作为分隔符),而shell 的行为类似于,至少在其默认配置中是这样zshkshbashzsh$IFSyashdash

在你的情况下,你应该使用

my_func () {
    local args
    args="$*"

    printf 'args: <%s>\n' "$args"
}

或者

my_func () {
    local args="$*"

    printf 'args: <%s>\n' "$args"
}

我在这里使用$*它是为了表明我正在从值列表构造单个字符串。该字符串将包含位置参数的值,由第一个字符分隔$IFS(默认为空格)。

我还用来printf确保获得用户提供的值的正确输出(请参阅为什么 printf 比 echo 更好?)。

另外,您的脚本应该用作#!/bin/dash第一行,而不是#!/bin/sh作为local标准语法的扩展sh

相关内容