当前位置: 首页>>技术教程>>正文


无法在Ubuntu 11.04上使用ctrl-c停止WEBrick 1.3.1

问题描述

我正在使用RVM,Ruby 1.9.2和Rails 3.0.7

从另一个终端进行的标准杀死进程也不起作用,但是杀死-9当然可以。

我发现了类似的问题CTRL+C to Webbrick server ignored,但尚不清楚该问题是否描述了相同的潜在问题。另外,该分辨率似乎不适用,因为我在Gemfile中未使用:git。

更新1 :(现在已经很旧了,请参阅下面的更新2,了解真正的消息)

我设法将问题缩小为一个 gems 。如果您提供以下测试脚本,您也可以看到该问题(假设您使用的是Ubuntu 11.04 …在10.04中没有问题)

rm -rf tmpkilltest

rvm 1.9.2
rvm --force gemset delete tmpkilltest
rvm gemset create tmpkilltest
rvm 1.9.2@tmpkilltest

gem install rails -v=3.0.7 --no-rdoc --no-ri
gem install sqlite3 -v=1.3.3 --no-rdoc --no-ri

rails new tmpkilltest

cd tmpkilltest

echo "gem 'barista', '1.0'" >> Gemfile

bundle

rails s

这个问题是由Rails与gem的交互引起的,这使我现在相信这个问题实际上与CTRL+C to Webbrick server ignored有关,尽管上面的测试案例表明,这个问题显然不是由:git应用于gem引起的。

更新2:

在更新1中,我提到我将其范围缩小为一个 gems 。当我经历那颗 gems 时,我最终找到了真正的罪魁祸首。 gem正在进行单个系统调用。我对测试脚本进行了非常小的修改,不再加载咖啡师gem,而是在application.rb的末尾附加一个系统调用。通过该系统调用,ctrl-c不起作用。删除系统调用,它确实起作用。

rm -rf tmpkilltest

rvm 1.9.2
rvm --force gemset delete tmpkilltest
rvm gemset create tmpkilltest
rvm 1.9.2@tmpkilltest

gem install rails -v=3.0.7 --no-rdoc --no-ri
gem install sqlite3 -v=1.3.3 --no-rdoc --no-ri

rails new tmpkilltest

cd tmpkilltest

bundle

echo "\`date\`" >> config/application.rb

rails s

这可以解释这个问题和CTRL+C to Webbrick server ignored之间看似相似的地方。我的直觉是,他们提到的gem也可以进行系统调用。

最佳方案

我宁愿发表评论,也不愿为此添加答案,但代表不足。

我遇到了同样的问题,发现在键入ctrlc之后恢复(使用fg),然后暂停(如上所述,使用ctrlz)可以解决问题。

所以配方是:

  1. ctrlc(立即不执行任何操作)

  2. ctrlz(暂停WEBrick,返回Shell)

  3. fg(恢复WEBrick,立即使用SIGINT进行操作)

    lampadmin@lampadmin-DX4840:/var/www/rails/agences$ r s
    => Booting WEBrick
    => Rails 3.0.5 application starting in development on http://0.0.0.0:3000
    => Call with -d to detach
    => Ctrl-C to shutdown server
    [2011-05-14 14:25:36] INFO  WEBrick 1.3.1
    [2011-05-14 14:25:36] INFO  ruby 1.9.2 (2011-02-18) [x86_64-linux]
    [2011-05-14 14:25:36] INFO  WEBrick::HTTPServer#start: pid=2585 port=3000
    

    ^ C^Z(<-ctrl-c,然后ctrl-z)

    [1]+  Stopped                 rails s
    lampadmin@lampadmin-DX4840:/var/www/rails/agences$ fg
    rails s
    [2011-05-14 14:25:45] INFO  going to shutdown ...
    [2011-05-14 14:25:45] INFO  WEBrick::HTTPServer#start done.
    Exiting
    

次佳方案

我遇到类似的问题,一直在使用Ctrl + Z暂停作业,然后使用kill -9 %1杀死第一个暂停的作业。回旋处杀死它的方法,但是它起作用。

有关更多信息,请参见超级用户的此问题:https://superuser.com/questions/243460/what-to-do-when-ctrl-c-cant-kill-a-process

第三种方案

我相信^C无法杀死WEBrick服务器,因为该服务器创建了一个新会话:

webrick/server.rb中:

  class Daemon     def Daemon.start       exit!(0) if fork       Process::setsid       exit!(0) if fork       Dir::chdir("/")       File::umask(0)       STDIN.reopen("/dev/null")       STDOUT.reopen("/dev/null", "w")       STDERR.reopen("/dev/null", "w")       yield if block_given?     end   end 

(rack/server.rb中存在非常相似的代码,因此,如果要通过机架启动WEBrick,则可能要忽略-D--daemonize命令行选项。)

setsid(2)的联机帮助页中:

   setsid() creates a new session if the calling process is not    a process group leader.  The calling process is the leader of    the new session, the process group leader of the new process    group, and has no controlling tty. 

没有控制tty意味着终端产生的信号(^Z SIGTSTP^\ SIGKILLSIGTTINSIGTTOU等)即使已在该终端上启动也无法到达该过程。链接已切断。

第四种方案

好的,问题已为我解决。我最近将其作为Ubuntu标准更新的一部分进行了内核更新,从而解决了该问题。

另外,这里是对该问题的精彩讨论,它说明了根本原因是2.6.38(http://redmine.ruby-lang.org/issues/4777)中引入的内核回归。

回归已得到修补,看起来该修补程序最近已成为Ubuntu的更新程序,因此,如果您受到此问题的影响,则应应用最新更新。

第五种方案

在Mac OS X上,这也发生在我身上。

令人惊讶的是,RackWEBrick都没有设置自定义信号处理程序。我将其放在机架应用程序的call方法中,它告诉我SIGINT的DEFAULT处理程序是当前处理程序(返回字符串"DEFAULT"):

p Signal.trap('INT', 'DEFAULT')

我怀疑在红 gems 的select中发生了某种情况,正在捕获信号。

这是两种将其停止服务器的方法:

1)按ctrl-z暂停。然后kill -ABRT pid_or_job_id。我不知道该如何退出”cleanly”。这很烦人,但您不必添加任何代码。

2a)如果您使用的是Rack,请在致电Rack::Handler::WEBrick.run之前添加此权限:

Signal.trap('INT') {
  Rack::Handler::WEBrick.shutdown
}

2b)如果您使用香草WEBrick

Signal.trap('INT') { server.shutdown }

其中server是您的WEBrick服务器对象。

如果您将经常使用SIGINT,则这些功能很好。您可能还想为TERMHUP添加处理程序。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/10238.html,未经允许,请勿转载。