当 运行 ruby 代码在带有 capistrano 的远程服务器上时,如何要求用户输入?

How to ask for user input when running ruby code on remote server with capistrano?

我想在 运行 远程服务器上的 capistrano 任务时确认操作:

task :do_someting do
  on roles(:primary) do
    within release_path do
      with rails_env: fetch(:rails_env) do
        execute :rails, :runner,
          %Q['require "do_something"; Do::Something.()']
      end
    end
  end
end

`DoSomethig 看起来像这样:

require "highline/import"

class DoSomething

  def self.call
    query_db_for_objects.each do |obj|
      answer = ask "Are you sure to do something with #{obj}? (y/n)"
      rerun unless answer == 'y'
      do_something
    end
  end

end

来自 highline gem 的方法 ask 从远程服务器请求时似乎不起作用,命令 bundle exec cap production do_something 永远挂起。

当 运行 这个 capistrano 任务时,如何从远程服务器请求用户输入?

我能够使用以下 ruby 代码从远程服务器读取用户答案

task :do_someting do

  class ConfirmHandler
    def on_data(command, stream_name, data, channel)
      if data.to_s =~ /\?$/
        prompt = Net::SSH::Prompt.default.start(type: 'confirm')
        response = prompt.ask "Please enter your response (y/n)"
        channel.send_data "#{response}\n"
      end
    end
  end

  on roles(:primary) do
    within release_path do
      with rails_env: fetch(:rails_env) do
        execute :rails, :runner,
          %Q['require "do_something"; Do::Something.()']
      end
    end
  end

end

其中 Do::Something 具有如下所示的 ask_user 方法:

class Do::Something

  def self.call
    answer = ask_user
    puts "Answer is: #{answer}"
  end

  def self.ask_user
    puts 'Do something?'
    `read response; echo $response`
  end

end