【问题标题】:How to emulate Ctrl+C in Ruby?如何在 Ruby 中模拟 Ctrl+C?
【发布时间】:2017-04-21 22:42:39
【问题描述】:

我有一个包含 IO.popen 调用的 Ruby 脚本。我可以使用 CTRL+C 取消 popen 调用(我使用 Signal.trap("SIGINT"),然后导致我调用 kill -2 #{popen_pid})。这很好用,当我按下 CTRL+C 时,kill -2 会导致 popen 进程在结束之前运行一些清理。

我的问题:当 popen 过程花费太长时间时,我也希望能够有同样的行为。但是,我无法模拟 CTRL+C 行为。在 ruby​​ 脚本的 pid 上使用 Process.kill 最终只会结束所有事情而没有进行清理,并且在 popen 进程上运行 Process.kill 什么也不做。我尝试使用反引号直接访问 shell,在 ruby​​ 脚本的 pid 和 popen pid 上调用 kill -2,但这些也不做任何事情。

有人有什么建议吗?

【问题讨论】:

    标签: ruby signals


    【解决方案1】:

    可能很难得到关于终止进程的答案,尤其是在访问 shell 时。一个平台上的解决方案可能不适用于其他平台。我建议您使用 Timeout,而不是试图通过杀死进程的麻烦,如果您的 IO.popen 调用花费的时间比您想要的要长,那么您可以在救援中进行清理。

    require 'timeout'
    
    seconds_to_wait = 10
    
    
    begin
      block_result = Timeout.timeout(seconds_to_wait) do
        # your IO stuff
      end
    rescue Timeout::Error
      puts "Ain't nobody got time for that!"
      # do your clean up here
    end
    

    【讨论】:

    • 这可以停止 popen 调用,但它本质上是用 -9 信号调用它。我需要-2,因为该进程需要运行一些内部清理...
    【解决方案2】:

    事实证明,我遇到问题主要是因为我想在 popen 进程发生时打印行,但也有一个超时,可以执行kill -2 以鼓励进程清理。

    最后,我最终在 popen 调用旁边启动了一个新线程(但在我开始从命令打印内容之前),一旦 popen 调用花费的时间超过我的等待时间,线程将调用kill -2

    Thread.new do
      $next_thread += 1
      this_thread = $next_thread - 1
      $active_threads[this_thread] = true
      start_time = Time.now
      while true
        break if not $active_threads[this_thread]
        minutes_elapsed = (Time.now - start_time) / 60
        if minutes_elapsed > 90
          inner_packer_pid = `ps -Af | tr -s ' ' | grep -v "grep" | grep "packer build" | cut -d' ' -f2 | sort | tail -n 1`.strip()
          `kill -2 #{inner_packer_pid}`
          cancel_build()
          break
        end
      end
      $active_threads[this_thread] = false
    end
    
    builders = Set.new
    
    packer_build = IO.popen("packer build -color=#{not $is_no_color} #{spec_file} 2>&1")
    $packer_build_pid = packer_build.pid
    packer_build.each do |line|
      puts line
    end
    

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 1970-01-01
      • 2013-01-01
      • 2017-11-03
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      相关资源
      最近更新 更多