bash 使用 su 以不同用户身份执行命令

bash execute commands as different user with su

我有一个最简单的问题,我不确定我做错了什么。

我有一个简单的 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=

我认为字符串中的 -- 有问题。我怎样才能避免这种情况?

此处 $@ 有两种重叠用法,您无意中发现了部分正确的解决方案。 -c 需要一个单词,而 "$@" 会产生 多个 个不同的单词。正确的解决方案是

su -s /bin/sh -c '"$@"' "$WWW_USER" _ "$@"

简短版本:您不想从当前参数构建命令字符串;你想将它们作为参数传递给硬编码的命令字符串,让新的 shell 适当地扩展内容。

细分:

  • -s /bin/sh - 使用 /bin/sh 而不是相应用户的登录名 shell
  • -c '"$@"' 运行 命令 "$@",根据需要。请注意,这是一个硬编码值;新的 shell 将在启动后正确扩展其位置参数。
  • "$WWW_USER" - 指定用户将运行和shell设为
  • _ - 在 shell 中指定 [=20=] 的值为 运行。您可能不关心这个值是什么;你只需要一些占位符来防止你的第一个真正的参数被视为 [=20=].
  • 的值
  • "$@"current 位置参数作为参数传递给新的 shell,这将扩展 its "$@" 到这些值。