我有一个 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>
阅读local
Ubuntu Wiki 的“Dash as /bin/sh”页面中的部分,看起来 Dash 正在local args="$@"
像这样扩展产品线:
local args=foo bar baz
因此只将“foo”放入并将和args
声明为(本地?)变量。事实上,如果我在参数中添加并运行它,它似乎确认我正在添加变量:bar
baz
echo "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 的行为类似于,至少在其默认配置中是这样zsh
。ksh
bash
zsh
$IFS
yash
dash
在你的情况下,你应该使用
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
。