在rake任务中执行'sudo su'命令

时间:2011-11-25 14:58:16

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1

我正在开发Rails v2.3应用程序。并在 Ubuntu 计算机上使用MySQL v5.1。

我有一个 rake 任务来停止启动 mysql数据库,如下所示:

namespace :db do
  task :some_db_task => :environment do
       ...

       exec 'sudo /etc/init.d/mysql stop'
       ...
       exec 'sudo /etc/init.d/mysql start' 
  end
end

正如您在上面的代码中看到的那样,我使用sudo来确保执行命令。但是,由于这个sudo,当我运行 rake 任务时,会有一个提示,要求我输入root密码,尽管rake任务已成功运行。

我想避免密码输入的事情,所以我想我可以执行shell命令首先更改为root用户,然后停止/启动MySQL,所以我将代码更改为以下内容:

namespace :db do
  task :some_db_task => :environment do
       ...

       exec 'sudo su'
       exec '/etc/init.d/mysql stop'
       ...
       exec '/etc/init.d/mysql start' 
  end
end

请参阅,我首先添加了sudo su命令。现在我再次运行我的rake任务,但是,令人惊讶的是rake任务一直运行到 exec 'sudo su' 然后它停止,其余的代码甚至都没有运行。为什么?如何摆脱它?

(一般情况下,我不希望在运行MySQL启动和停止的rake任务期间输入root密码)

3 个答案:

答案 0 :(得分:4)

你有几个问题。

首先,Kernel#exec方法不会返回。请参阅API说明:

  

通过运行给定的外部命令替换当前进程。

其次,从Ruby执行sudo真的很奇怪。你能简单地执行sudo rake db:some_db_task吗?

<强>已更新

第三,Kernel#exec不会返回,但Kernel#system会返回。如果您真的想在rake脚本中sudo,则需要使用Kernel#system并在每个命令中执行sudo。例如:

   system 'sudo /etc/init.d/mysql stop'
   system 'sudo /etc/init.d/mysql start'

system 'sudo su'不起作用。它将以root用户启动shell,当您离开shell时,Ruby进程将无法获得root权限。

答案 1 :(得分:1)

我建议为这两个命令创建shell别名。 Rails中的Rake任务并不是真正用于系统特定的事情。

将这些行添加到.bashrc中,以便更快地启动和停止。

alias mysql_start = 'sudo /etc/init.d/mysql start'
alias mysql_stop = 'sudo /etc/init.d/mysql stop'

如果您希望将此作为部署类型的情况,capistrano更适合工作。

答案 2 :(得分:0)

我认为你应该使用sudo for rake而不是自定义命令(即sudo rake db:some_db_task)? 或尝试第一次调用exec'sudo su',没有'sudo'的其他可执行文件,但我认为rake可以每次为新会话运行exec并且sudo su命令在下一个exec上关闭。

有关此问题的一些链接 http://www.ruby-forum.com/topic/69967