我发现 bash 脚本中的某些代码使用set -- env
前面的实际命令调用程序,例如:
set -- env GOPATH=/some/path go build ${PACKAGE}
这样做的理由是什么?是不是和刚才一样
env GOPATH=/some/path go build ${PACKAGE}
答案1
set -- env GOPATH=/some/path go build ${PACKAGE}
这不调用任何程序(好吧,它调用内置的set
,但不调用env
或go
)。它将位置参数($1
、$2
等,统称为列表"$@"
)设置为后面的单词--
,这样 if就是您拥有的$PACKAGE
字符串hello world
$ PACKAGE='hello world'
$ set -- env GOPATH=/some/path go build ${PACKAGE}
$ i=1; for param in "$@"; do printf '$%d = "%s"\n' "$i" "$param"; i=$((i+1)); done
$1 = "env"
$2 = "GOPATH=/some/path"
$3 = "go"
$4 = "build"
$5 = "hello"
$6 = "world"
即,它将参数$1
通过 to设置$6
为 后的值--
,并且不会执行env
or go
。
如果有人说
"$@"
这将执行该命令。 "$@"
扩展到位置参数(单独引用)。
在eg中bash
,它相当于设置命名数组的值:
array=( env GOPATH=/some/path go build ${PACKAGE} )
这也不执行env
or go
。
后来,使用
"${array[@]}"
将执行该命令行。
"$@"
请注意, and中的双引号"${array[@]}"
是有意且重要的。如果没有双引号,这些列表的元素将在空格上拆分为单独的单词(就像上面使用不带引号时将字符串hello world
拆分为两个一样${PACKAGE}
),并且 shell 还将对生成的单词执行文件名通配。