我有一个最简单的问题,我不确定我做错了什么。
我有一个简单的shell脚本使用/ bin / sh
在脚本中我有以下内容:
exec_as_wwwdata() {
if [ $(whoami) = ${WWW_USER} ]]; then
$@
else
su -s /bin/sh -c '$@' ${WWW_USER}
fi
}
我用
来称呼它exec_as_wwwdata composer config -g github-oauth.github.com $COMPOSER_GITHUB_TOKEN
它什么也没做,没有任何错误信息。 如果我直接在脚本中调用以下内容
su -s /bin/sh -c 'composer config -g github-oauth.github.com $COMPOSER_GITHUB_TOKEN' ${WWW_USER}
它有效。
我在这里做错了什么?
根据反馈,我已将其更改为
exec_as_wwwdata() {
if [ $(whoami) = ${WWW_USER} ]]; then
$@
else
su -s /bin/sh -c '"$@"' "$WWW_USER" _ "$@"
fi
}
虽然我用以下参数调用它
exec_as_wwwdata /usr/local/bin/php /usr/local/bin/composer create-project --repository-url=xxxx .
我收到以下错误消息
su: unrecognized option '--repository-url=
我认为字符串中存在问题。我该怎么逃避呢?
答案 0 :(得分:1)
此处$@
有两个重叠用途,您无意中偶然发现了部分正确的解决方案。 -c
需要一个单词,而"$@"
会产生多个不同的单词。正确的解决方案是
su -s /bin/sh -c '"$@"' "$WWW_USER" _ "$@"
简短版本:您不想从当前参数构建命令字符串;你想把它们作为参数传递给硬编码的命令字符串,让新的shell适当地扩展。
细分:
-s /bin/sh
- 使用/bin/sh
代替相应用户的登录shell -c '"$@"'
根据需要运行命令"$@"
。请注意,这是一个硬编码值;一旦启动,新shell将正确扩展其位置参数。"$WWW_USER"
- 指定运行shell的用户_
- 在正在运行的shell中指定$0
的值。你可能不在乎这个价值是什么;你只需要一些占位符来防止你的第一个真实论点被视为$0
的值。"$@"
将当前位置参数作为参数传递给新shell,这会将其 "$@"
扩展为这些值。