如何在cap shell命令中使用sudo作为参数?

时间:2012-08-14 14:04:05

标签: 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选项时需要包文件。没有包装,所以它失败了。

当我尝试从cap shell运行grep sudo等时,会出现类似的问题。

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

1 个答案:

答案 0 :(得分:0)

AFAICS,这个问题似乎是Capistrano的一个错误。因此,请向the BTS报告。

无论如何,您可以通过覆盖自己的Capistrano::Shell::exec_command()命令中的私有方法cap来解决此问题。

  1. 创建名为mycap.rb
  2. 的文件
  3. 复制/usr/bin/cap
  4. 中的原始mycap.rb
  5. 添加require 'capistrano/shell'
  6. exec_command()
  7. 中添加mycap.rb
  8. /\bsudo\b/
  9. 之类的内容替换正则表达式/^sudo\b/
  10. 执行mycap.rb而不是原始cap命令
  11. 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
    

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