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

Har*_*tts 6 dash shell-script

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

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

my_func "$@"
Run Code Online (Sandbox Code Playgroud)

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

$ bash foo.sh foo bar baz
args: <foo bar baz>
Run Code Online (Sandbox Code Playgroud)

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

$ dash test.sh foo bar baz
args: <foo>
Run Code Online (Sandbox Code Playgroud)

阅读Ubuntu Wiki 的“Dash as /bin/sh”页面中的部分local,似乎 Dash 正在local args="$@"像这样扩展该行:

$ bash foo.sh foo bar baz
args: <foo bar baz>
Run Code Online (Sandbox Code Playgroud)

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

$ dash test.sh foo bar baz
args: <foo>
Run Code Online (Sandbox Code Playgroud)

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

Kus*_*nda 5

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

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

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

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

    printf 'args: <%s>\n' "$args"
}
Run Code Online (Sandbox Code Playgroud)

或者

my_func () {
    local args="$*"

    printf 'args: <%s>\n' "$args"
}
Run Code Online (Sandbox Code Playgroud)

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

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

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