我想以非 root 用户身份执行作曲家。因此,我将主作曲家可执行文件重命名为composer-call
,然后创建另一个名为composer
.
#composer.sh
su nginx -c "composer-call ${@}"
现在,当我执行它时composer --version
,它可以工作,但同时传递一些更复杂的参数,如下composer create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction
所示错误
+ su nginx -c 'composer-call create-project' drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction
su: unrecognized option: stability
更新1
根据杰夫的以下回答,我尝试了他的答案,但它给了我另一个错误。期待更好的解决方案。
composer-call: line 2: can't open ?php: no such file
composer-call: line 3: /bin: Permission denied
+ su nginx -- composer-call composer-call docker-php-entrypoint docker-php-ext-configure docker-php-ext-enable docker-php-ext-install docker-php-source drupal drush pear peardev pecl phar phar.phar php php-config phpdbg phpize This file is part of Composer.
su: must be suid to work properly
+ su nginx -- composer-call composer-call docker-php-entrypoint docker-php-ext-configure docker-php-ext-enable docker-php-ext-install docker-php-source drupal drush pear peardev pecl phar phar.phar php php-config phpdbg phpize
su: must be suid to work properly
composer-call: line 6: syntax error: unexpected word (expecting ")")
注意:composer-call 是一个 php cli 脚本。
答案1
用于--
分隔目标用户的命令,以便su
不会尝试解析其他参数:
#composer.sh
su nginx -- composer-call "${@}"
举个例子:
user1的composer.sh:
#!/bin/sh
set -x
su otheruser -- /home/otheruser/composer-call "$@"
/home/otheruser/composer-call:
#!/bin/sh
echo Hi, I am composer-call, with arguments:
printf '%s\n' "$@"
行动中:
./composer.sh create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction
+ su otheruser -- /home/otheruser/composer-call create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction
Password:
Hi, I am composer-call, with arguments:
create-project
drupal-composer/drupal-project:8.x-dev
some-dir
--stability
dev
--no-interaction
答案2
这是因为"$@"
扩展为单独的单词,并且第二个单词(--stability
在您的情况下)被视为 的选项su
。这是ls
用作命令的示例:
#composer.sh
set -x
su nginx -c "ls $@"
输出1:
$ ./composer.sh -l -a
++ su nginx -c 'ls -l' -a
su: invalid option -- 'a'
Try 'su --help' for more information.
请注意,只有第一个参数 ( -l
) 进入传递给 的字符串-c
。这就是你的--version
案例有效的原因。相反,$@
您应该使用$*
将其放在双引号中时扩展为单个单词:
#composer.sh
set -x
su nginx -c "ls $*"
输出2:
$ ./composer.sh -l -a
++ su nginx -c 'ls -l -a'
total 12
drwxr-xr-x 2 root root 4096 Apr 22 11:05 .
drwxr-xr-x 1 root root 4096 Apr 22 11:05 ..
-rwxr-xr-x 1 root root 28 Apr 22 11:05 composer.sh
-rw-r--r-- 1 root root 0 Apr 22 11:05 test.txt
请注意,现在所有参数都会-c
产生正确的结果。
man bash
您可以在参考资料 部分中详细了解它Special Parameters
。
答案3
最后将composer命令封装在here-doc块中对我有帮助
#!/bin/sh
su nginx -s /bin/sh <<EOF
composer-call "$@"
EOF
我使用下面的代码以编程方式创建上面的包装器脚本。 :)
printf '%s\n' "#!/bin/sh" "su nginx -s /bin/sh <<EOF" "composer-call \$@" "EOF" > /usr/local/bin/composer
除了它苏执行也是一个不错的选择。这是一个小软件,可以像这样安装apk add su-exec