在脚本中运行时,su -c命令失败

时间:2016-06-12 13:23:10

标签: bash unicorn

我试图通过数字海洋ubuntu服务器上的shell脚本发出一个unicorn命令。命令是:

su - xxx -c cd /home/xxx/apps/app_name && rbenv rehash && rbenv local 2.3.1 && /home/xxx/apps/app_name/bin/unicorn -c /home/xxx/apps/app_name/config/unicorn.rb -E production -D

此命令在命令行上发出时有效,但如果我将其放入如下脚本:

#!/bin/sh

USER=xxx

APP_ROOT=/home/xxx/apps/app_name
RBENV_RUBY_VERSION=2.3.1

SET_PATH="cd $APP_ROOT && rbenv rehash && rbenv local $RBENV_RUBY_VERSION"
RAILS_ENV=production
UNICORN="$APP_ROOT/bin/unicorn"
UNICORN_OPTS="-c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV -D"
CMD="$SET_PATH && $UNICORN $UNICORN_OPTS"

su - $USER -c "$CMD"

我收到此错误:-su: rbenv: command not found

如果删除$CMD周围的引号,则会出现此错误:su: invalid option -- 'E'

有谁知道如何解决这个问题?

根据下面的评论,我通过添加rbenv的路径来修改脚本:

RBENV_ROOT="/home/$USER/.rbenv"
SET_PATH="cd $APP_ROOT && $RBENV_ROOT/bin/rbenv rehash && $RBENV_ROOT/bin/rbenv local $RBENV_RUBY_VERSION"

当我现在运行时,我收到以下错误: -su: cd /home/xxx/apps/app_name && /home/xxx/.rbenv/bin/rbenv rehash && /home/xxx/.rbenv/bin/rbenv local 2.3.1 && /home/xxx/apps/app_name/bin/unicorn /home/xxx/apps/app_name/config/unicorn.rb -E production -D: No such file or directory

2 个答案:

答案 0 :(得分:1)

你得到不同结果的原因是,shell拆分命令实际上是分成多个部分:

su - xxx -c cd /home/xxx/apps/app_name 
&& rbenv rehash
&& rbenv local 2.3.1 
&& /home/xxx/apps/app_name/bin/unicorn -c /home/xxx/apps/app_name/config/unicorn.rb -E production -D

对于每个换行符,在shell中调用一个新命令(作为您的用户,而不是替换者)。

上述方法表示使用su致电'-' 'xxx' '-c' 'cd' '/home/xxx/apps/app_name',如果成功,则使用rbenv致电'rehash',依此类推......

在你的脚本中,所有这些都被解释为一个参数:

# Terminal:
su - user -c ls && echo 1
# Script
su - user -c 'ls && echo 1'

说完所有这些后,应该清楚您的脚本正在执行它应该执行的操作,但rbenv不在$PATHsu内。你可以使用rbenv的绝对路径来解决这个问题:

su - xxx -c 'cd /home/xxx/apps/app_name && /path/to/rbenv ...'

需要注意的一些事项:大写变量名称保留给environment variables,因此您应该考虑使用小写名称。如果不将parameter expansions括在双引号中,则会word splittingglobbing

答案 1 :(得分:1)

在您的情况下,su命令仅应用于cd命令。

Shell会将您的命令拆分为以下命令,并分别评估它们并使用它们的返回代码来(部分)评估&&表达式:

su - xxx -c cd /home/xxx/apps/app_name
rbenv rehash
rbenv local 2.3.1
/home/xxx/apps/app_name/bin/unicorn -c /home/xxx/apps/app_name/config/unicorn.rb -E production -D

因此,当我们绘制评估树时,它将如下所示:

shell
 `-- &&
     |-- su
     |   `-- shell
     |       `-- cd
     |-- rbenv
     |-- rbenv
     `-- unicorn

所以将su应用于整个事物(如你所愿)将其包装在引号中:

su - xxx -c 'cd /home... && rbenv ... && ...'

因此,当我们绘制固定命令的评估树时,它将如下所示:

shell
 `-- su
     `-- shell
         `-- &&
             |-- cd
             |-- rbenv
             |-- rbenv
             `-- unicorn