我试图通过数字海洋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
答案 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
不在$PATH
内su
内。你可以使用rbenv
的绝对路径来解决这个问题:
su - xxx -c 'cd /home/xxx/apps/app_name && /path/to/rbenv ...'
需要注意的一些事项:大写变量名称保留给environment variables,因此您应该考虑使用小写名称。如果不将parameter expansions括在双引号中,则会word splitting和globbing。
答案 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