Ruby 如何在cap shell命令中将sudo用作参数?

Ruby 如何在cap shell命令中将sudo用作参数?,ruby,capistrano,Ruby,Capistrano,当我尝试运行将sudo用作参数而不是命令的cap shell命令时,将执行仅与sudo用作命令时相关的替换 例如: $ cap shell cap> rpm -q sudo 由于shell.rb包含 command = command.gsub(/\bsudo\b/, "sudo -p '#{configuration.sudo_prompt}'") 这会把命令变成 rpm -q sudo -p '\\''sudo password: '\\'' rpm命令在遇到-p选项时需要一个包

当我尝试运行将sudo用作参数而不是命令的cap shell命令时,将执行仅与sudo用作命令时相关的替换

例如:

$ cap shell
cap> rpm -q sudo
由于shell.rb包含

command = command.gsub(/\bsudo\b/, "sudo -p '#{configuration.sudo_prompt}'")
这会把命令变成

rpm -q sudo -p '\\''sudo password: '\\''
rpm命令在遇到-p选项时需要一个包文件。没有包,所以它失败了

当我试图从capshell运行grepsudo等时,也会出现类似的问题


有没有办法在cap shell命令中使用sudo作为参数?

AFAICS,这个问题似乎是Capistrano中的一个bug。所以,请向我报告

无论如何,您可以通过在自己的cap命令中重写私有方法Capistrano::Shell::exec_命令来解决这个问题

创建一个名为mycap.rb的文件 在mycap.rb中复制原始/usr/bin/cap 添加“capistrano/shell” 在mycap.rb中添加exec_命令 将regexp/\bsudo\b/替换为类似于/^sudo\b的内容/ 执行mycap.rb而不是原来的cap命令 mycap.rb的内容应该如下所示:

#!/usr/bin/env ruby

require 'capistrano/cli'
require 'capistrano/shell'

module Capistrano
  class Shell
    private

    def exec_command(command, servers)
      command = command.gsub(/^sudo\b/, "sudo -p '#{configuration.sudo_prompt}'")
      processor = configuration.sudo_behavior_callback(Configuration.default_io_proc)
      sessions = servers.map { |server| configuration.sessions[server] }
      options = configuration.add_default_command_options({})
      cmd = Command.new(command, sessions, options.merge(:logger => configuration.logger), &processor)
      previous = trap("INT") { cmd.stop! }
      cmd.process!
    rescue Capistrano::Error => error
      warn "error: #{error.message}"
    ensure
      trap("INT", previous)
    end
  end
end

Capistrano::CLI.execute

请注意,command.gsub中的\b替换为^。但是其他一切都是一样的。

AFAICS,这个问题似乎是Capistrano中的一个bug。所以,请向我报告

无论如何,您可以通过在自己的cap命令中重写私有方法Capistrano::Shell::exec_命令来解决这个问题

创建一个名为mycap.rb的文件 在mycap.rb中复制原始/usr/bin/cap 添加“capistrano/shell” 在mycap.rb中添加exec_命令 将regexp/\bsudo\b/替换为类似于/^sudo\b的内容/ 执行mycap.rb而不是原来的cap命令 mycap.rb的内容应该如下所示:

#!/usr/bin/env ruby

require 'capistrano/cli'
require 'capistrano/shell'

module Capistrano
  class Shell
    private

    def exec_command(command, servers)
      command = command.gsub(/^sudo\b/, "sudo -p '#{configuration.sudo_prompt}'")
      processor = configuration.sudo_behavior_callback(Configuration.default_io_proc)
      sessions = servers.map { |server| configuration.sessions[server] }
      options = configuration.add_default_command_options({})
      cmd = Command.new(command, sessions, options.merge(:logger => configuration.logger), &processor)
      previous = trap("INT") { cmd.stop! }
      cmd.process!
    rescue Capistrano::Error => error
      warn "error: #{error.message}"
    ensure
      trap("INT", previous)
    end
  end
end

Capistrano::CLI.execute

请注意,command.gsub中的\b替换为^。但其他一切都是一样的。

嗯。。。1我在不需要“rubygems”的情况下进行了测试并工作。不知道为什么。2啊,原作者不再维护capistrano了。最好向我报告。我已经更新了url。是的。Capistrano很难知道字符串sudo实际上是远程shell将要执行的命令,或者只是一个字符串/参数。您可以使用与远程shell相同的解析器,但这取决于用户的设置。您需要知道sudo是否实际在远程执行的原因是您需要添加提示选项。作为一个用户,你能在需要的时候提供选项而不是让Capistrano猜测吗?嗯。。。1我在不需要“rubygems”的情况下进行了测试并工作。不知道为什么。2啊,原作者不再维护capistrano了。最好向我报告。我已经更新了url。是的。Capistrano很难知道字符串sudo实际上是远程shell将要执行的命令,或者只是一个字符串/参数。您可以使用与远程shell相同的解析器,但这取决于用户的设置。您需要知道sudo是否实际在远程执行的原因是您需要添加提示选项。作为一个用户,你能在需要的时候提供选项而不是让Capistrano猜测吗?