在其他应用程序的上下文中运行命令

时间:2013-08-08 04:47:15

标签: ruby-on-rails capistrano bundler system-calls

我在同一台服务器上有两个rails应用程序,我们称之为A和B.

我正在尝试让应用A通过应用B自己的capistrano任务重新启动应用B.不幸的是,即使在访问应用程序B的目录之后,它也试图运行应用程序A的capistrano。我错过了什么吗?

示例代码

system("cd /apps/appB/current && pwd && bundle exec cap:restart")

pwd正确返回appB的路径(/ apps / appB / current),但是,有一个回溯:cap:restart。这是因为它仍在尝试在appA的上下文中运行cap命令,例如

/apps/appA/shared/bundle/ruby/1.9.1/gems/capistrano-2.15.4/lib/capistrano/configuration/loading.rb:152:in 'require': cannot load such file -- airbrake/capistrano (LoadError) from /apps/appA/shared/bundle/ruby/1.9.1/gems/capistrano-2.15.4/lib/capistrano/configuration/loading.rb:152:in 'require'.

我试过没有'捆绑exec',并尝试了一些其他方式进行系统调用。我还在另一个目录中创建了一个bash脚本,并尝试以这种方式运行它。

所描述的所有方法都表现出相同的行为。

非常感谢您的帮助=)

2 个答案:

答案 0 :(得分:1)

您需要使用Bundler.with_clean_env来确保您的子流程不会获取当前的Bundler环境:

Bundler.with_clean_env do
  system("cd /apps/appB/current && pwd && bundle exec cap:restart")
end

这与Install bundle of gem within other rails application

基本相同

答案 1 :(得分:0)

由于您说您的应用使用了Unicorn,因此您可以从应用A发送给应用B(或其他方式)。

阅读本页:http://unicorn.bogomips.org/SIGNALS.html

每个应用程序唯一需要知道的是另一个应用程序的pidfile路径。所以看看你的Unicorn配置,看看它存储在哪里。

您可以从该pid文件中读取PID并从Ruby中删除它:

pid = File.read(path_to_other_application_pidfile).chop
Process.kill("USR2", pid)

或者您可以使用反引号来执行shell命令

`kill -s USR2 \`cat #{path_to_other_application_pidfile}\``