【问题标题】:How to run app via Ruby shell command, when same command works on command line当相同的命令在命令行上运行时,如何通过 Ruby shell 命令运行应用程序
【发布时间】:2018-12-19 04:27:59
【问题描述】:

我有一个简单的 Ruby (Sinatra) 服务器,它可以从带有ruby app.rb 的命令行毫无问题地启动。但是当我通过我的command line app 执行相同的命令时,无论是使用`ruby app.rb` 还是使用system("ruby app.rb"),我都会收到此错误:

app.rb:1:in `require': cannot load such file -- sinatra (LoadError)
    from app.rb:1:in `<main>'

app.rb 的开头就是require 'sinatra'。 Sinatra gem 安装在我的系统中,当然;我不明白为什么解释器的行为就像它不存在一样。

在进行故障排除时,我决定将 Sinatra 添加到调用 app.rb 的命令行应用程序的 Gemfile 中。瞧,现在父进程可以访问 Sinatra,现在它可以工作了(即,system(app.rb) 成功启动了 Sinatra 服务器)。但是当我退出命令行应用程序时,Sinatra 服务器总是在那里,说:

[2018-12-18 23:17:37] INFO  WEBrick 1.3.1
[2018-12-18 23:17:37] INFO  ruby 2.4.0 (2016-12-24) [x86_64-linux]
== Sinatra (v2.0.4) has taken the stage on 4567 for development with backup from WEBrick
[2018-12-18 23:17:37] INFO  WEBrick::HTTPServer#start: pid=27384 port=4567

所以我必须 Ctrl-c 退出命令行应用程序。

问题:有没有办法产生一个独立的 Sinatra 进程/服务器,就像我试图用 system("ruby app.rb") 做的那样,而不在父应用程序(命令行应用程序)中安装它?我也尝试使用 Process.fork,然后使用 Process.wait,但这没有帮助。

【问题讨论】:

  • system("ruby app.rb &amp;") 在单独的进程中启动它
  • 谢谢,但上述并没有真正解决问题。我仍然收到相同的错误消息:app.rb:1:in 'require': cannot load such file -- sinatra (LoadError) from app.rb:1:in '&lt;main&gt;'
  • 我猜system 调用最终不在您期望的目录中(可能是实际安装 ruby​​ 的任何文件夹),您应该提供应用程序的绝对路径.rb 文件。在 Rails 世界中,我会尝试在它前面加上 Rails.root。不确定 Sinatra 是否有类似的东西可以轻松获取您的应用根目录。
  • 看起来是版本问题。您是否使用一些 ruby​​ 版本管理器,例如 rvmrbenv 或类似的?如果是,我建议你应该从你的脚本中导出相应的PATH,因为system 不会加载你所有的点文件。
  • 我怀疑@Nate 正在做某事。我会检查两者的环境。例如,当使用 --path 安装包时,bundler 将 GEM_HOME 环境变量设置为指向给定路径,工具可能是一个因素。如果 Sinatra 不在当前的 gem home 中,那么解释器就不会找到它。您可以自己将其添加到加载路径中,但这显然很麻烦。分叉不会改变环境。您可以先使用系统命令通过cding 检查应用程序目录,或者在 Sinatra 应用程序中操作加载路径来查看。

标签: ruby process fork sinatra


【解决方案1】:

自我回答,因为我找到了解决方案,没有其他人回答过:

不要只执行ruby app.rb,它本身在与周围程序相同的环境中运行,因此使用相同的Gemfile(忽略生成的脚本中提到的那个),执行:

system("BUNDLE_GEMFILE='./Gemfile' && ruby app.rb")

这就是它的全部内容!这告诉 Ruby 在运行程序时加载正确的 gemfile。


个人说明: 非常感谢在上面讨论这个问题的所有人,以及当地的 Ruby 小组、我最好的朋友和我 12 岁的程序员儿子(谁实际上提供了确切的代码)。现在我只需要弄清楚如何在不停止周围程序的情况下 stop 生成的进程。不能只使用“Ctrl-C”。但这是一个不同的问题!

【讨论】:

  • 很高兴你找到了答案(我们应该为一个 12 岁的孩子打败我们而感到自豪还是害怕?(0_º) :) 看看this flow chartProcess.kill
  • 哇,这是一张很棒的流程图。好的,我想我知道我要做什么了。
  • 我可能每天都在使用它,非常有帮助。我还可以推荐 Jesse Storimer 的《使用 Unix 进程》一书,但在这个主题上还有其他好东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 1970-01-01
  • 2019-02-05
  • 1970-01-01
  • 2012-06-01
  • 2016-06-03
  • 2020-08-13
相关资源
最近更新 更多