【问题标题】:execute 'sudo su' command in rake task在 rake 任务中执行“sudo su”命令
【发布时间】:2011-11-26 00:48:10
【问题描述】:

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

我有一个 rake 任务来stopstart 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 密码)

【问题讨论】:

  • sudo su 将生成一个交互式终端为root,并等待您使用它。你试图以错误的方式解决你的问题,如果你需要root 权限,你将需要一个密码(或者你的设置非常不安全)。
  • sudo su 是一种奇怪的说法 sudo -s

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


【解决方案1】:

你有几个问题。

首先,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 权限。

【讨论】:

  • 谢谢,如果我打算执行 sudo rake db:some_db_task,那么,在我的 rake 任务中,我是否需要在每个命令上都有 sudo?
  • sudo 将进程翻转到根级别,因此所有后续子进程都是根级别,除非特别降级。
  • @tadman:是的,sudo 会将进程翻转到根级别。但是,在这种情况下,它只会影响 rake 的子进程。 Ruby 脚本中的其余命令不会受到影响。我已经更新了我的答案。
  • 使用“系统”是我的 rake 任务的正确选择,因为 exec 不会返回进程,我只是注意到 exec 之后的所有代码都没有运行。谢谢Miaout
【解决方案2】:

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

将这些行添加到您的 .bashrc 以使其更快地启动和停止。

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

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

【讨论】:

  • 您还可以将该命令添加到/etc/sudoers 以不需要某些用户帐户的密码。
【解决方案3】:

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

关于这个问题的一些链接 http://www.ruby-forum.com/topic/69967

【讨论】:

  • 谢谢,如果我打算执行 sudo rake db:some_db_task,那么,在我的 rake 任务中,我是否需要在每个命令上都有 sudo?
  • 现在我无法测试它,但我认为 sudo 不需要更多,因为 exec 运行到 sudo rake 进程并且 rake 进程都准备好了 sudo privelegies
最近更新 更多