如何通过 sudo 运行 ruby

Posted

技术标签:

【中文标题】如何通过 sudo 运行 ruby【英文标题】:How to run ruby via sudo 【发布时间】:2013-07-23 22:36:46 【问题描述】:

您好,我正在创建一个用于监控 ruby​​ 程序的新初始化脚本。

NAME=differ
FILE_PATH=/home/amer/Documents/ruby_projects/differ/
PIDFILE=/home/amer/pid/differ.pid
PID=$$
EXEC='/home/amer/.rvm/rubies/ruby-2.0.0-p247/bin/ruby main_scheduler.rb'

do_start()
    echo "started"
    cd $FILE_PATH
    pwd
    $EXEC  >> init_log/output.log &
    echo $! > $PIDFILE
    echo "---------"
    echo `cat $PIDFILE`
    echo "all are DONE "


do_stop()
    PID=`cat $PIDFILE`
    echo $PID
    if ps -p $PID ; then
        kill -6  $PID
        echo "it is over"
    else
        echo "its not running"
    fi


case "$1" in
    start)
    echo $$
        echo -n "Starting script differ "
        do_start
        ;;
    stop)
        echo "stopping ...."
        do_stop
        ;;
    status)
        PID=`cat $PIDFILE`
        echo "STATUS $PID"
        if  ps -p $PID -f; then
            echo running
        else
            echo not running
        fi
        ;;
    restart|reload|condrestart)
        do_stop
        do_start
        ;;
    *)
        echo "Usage: /etc/init.d/blah start|stop"
        exit 1
        ;;
esac

exit 0

我的监控过程是

 check process differ with pidfile /home/amer/pid/differ.pid
if changed pid then exec "/etc/init.d/differ start"
 start program = "/etc/init.d/differ start" 
 stop program = "/etc/init.d/differ stop"
 if 5 restarts within 5 cycles then timeout

但是当我在我的监视器中执行启动服务时,状态是“执行失败”,我检查了监视器的日志文件,它说

       info     : 'differ' start: /bin/bash
       error    : 'differ' failed to start
       error    : 'differ' process is not running

当我分析问题的根源时。原因是 monit 以 root 身份运行,执行 ruby​​ 的脚本将作为 sudo /etc/init.d/differ.sh start 执行,但 ruby​​ 仅安装在用户 'amer' 中。我试过了

 sudo -u amer $EXEC >>init_log/output.log &

它将错误显示为

 amer@amer-Inspiron-1525:~$ /home/amer/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require': cannot load such file -- bundler/setup (LoadError)
from /home/amer/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require'
from main_scheduler.rb:2:in `<main>'

请帮助解决这个问题。我有两个 ruby​​ 版本。

     /home/amer/.rvm/rubies/ruby-2.0.0-p247/bin/ruby
     /home/amer/.rvm/bin/ruby

【问题讨论】:

【参考方案1】:

经过长时间的努力,我找到了解决这个问题的方法。 必须做两件事

1) 在脚本中导出你的 PATH,GEM_HOME,GEM_PATH

export PATH="/home/amer/.rvm/gems/ruby-2.0.0-p247@rails329/bin:/home/amer/.rvm/gems/ruby-2.0.0-p247@global/bin:/home/amer/.rvm/rubies/ruby-2.0.0-p247/bin:/home/amer/.rvm/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"   
export GEM_HOME=/home/amer/.rvm/gems/ruby-2.0.0-p247@rails329
export GEM_PATH=/home/amer/.rvm/gems/ruby-2.0.0-p247@rails329:/home/amer/.rvm/gems/ruby-2.0.0-p247@global

2) 使用 rvmsudo bundle exec ruby​​ "filename"(使用完整路径)

 rvmsudo -u amer  /home/amer/.rvm/gems/ruby-2.0.0-p247@rails329/bin/bundle exec  /home/amer/.rvm/rubies/ruby-2.0.0-p247/bin/ruby main_scheduler.rb&

它对我有用。希望对大家有用。

【讨论】:

【参考方案2】:

当我想在 init 中运行 ruby​​ 脚本时,我会这样做:

我切换到超级用户并安装 rvm。这不会导致您的单用户安装出现问题。

我把它放在初始化脚本中:

/usr/local/rvm/bin/rvm-shell 'yourgemset' -c 'ruby pathtoyourscript/yourscript.rb'

例子:

/usr/local/rvm/bin/rvm-shell 'jruby-1.7.4' -c 'ruby /home/someone/service.rb'

提示:需要在该 gemset 中安装所有必需的 gem。

做这一切的正确方法是创建一个 rvm 包装脚本 (see example),但我发现我的方法更容易用于没有很多 gemset 的简单设置。

【讨论】:

【参考方案3】:

您的环境似乎丢失了。替换

sudo -u amer $EXEC >>init_log/output.log &

su -s /bin/bash - amer -c "$EXEC >> init_log/output.log 2>&1" &

这应该会正确设置您的 shell 环境。如果您之前运行过sudo .. &gt;&gt; log,则日志文件可能归根用户所有。改变它,否则它会失败。我还添加了 STDERR 到 STDOUT 的重定向,因为您可能对错误消息感兴趣。

【讨论】:

尝试在EXEC='ruby main_scheduler.rb'中使用ruby的完整路径。 @user1475089 使用su - &lt;user&gt; 而不是sudo -u &lt;user&gt;。那应该可以。

以上是关于如何通过 sudo 运行 ruby的主要内容,如果未能解决你的问题,请参考以下文章

如何通过多个 sudo 和 su 命令找到原始用户?

运行 sudo gem install fastlane -NV 在安装 fastlane ruby​​zip 需要 ruby​​ version >= 2.4 时抛出错误

如何从需要SUDO的php调用shell脚本?

如何从需要 SUDO 的 php 调用 shell 脚本?

如何在命令行上使用相同的命令,通过Ruby shell命令运行app

怎么在ubuntu下不通过sudo使用root权限