Ruby 如何在cap shell命令中将sudo用作参数?
当我尝试运行将sudo用作参数而不是命令的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选项时需要一个包
$ 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猜测吗?