2

我想要实现的是一个 capistrano3 任务,它在所有服务器上执行一个日志文件 grep - 这将节省大量时间,因为我们有很多服务器,因此手动或什至编写脚本但顺序需要很长时间。

我有一个粗略的边缘任务,它实际上可以工作,除非其中一个服务器没有为 grep 返回任何内容。在这种情况下,整个命令都会失败。

因此想知道是否有办法设置capture接受空退货。

namespace :admin do
  task :log_grep, :command, :file do |t,args|
    command = args[:command] || 'ask for a command'
    file = args[:file] || 'log_grep_results'
    outs = {}
    on roles(:app), in: :parallel do
      outs[host.hostname] = capture(:zgrep, "#{command}")
    end

    File.open(file, 'w') do |fh|
      outs.each do |host,out|
        fh.write(out)
      end
    end
  end
end
4

2 回答 2

4

如果其他人提出这个问题,这里的解决方案 -raise_on_non_zero_exit: false

我想了:

resp = capture %([ -f /var/run/xxx/xxx.pid ] && echo "ok")

错误:

SSHKit::Command::Failed: [ -f /var/run/xxx/xxx.pid ] && echo "ok" exit status: 1
[ -f /var/run/xxx/xxx.pid ] && echo "ok" stdout: Nothing written
[ -f /var/run/xxx/xxx.pid ] && echo "ok" stderr: Nothing written

解决方案:

resp = capture %([ -f /var/run/xxx/xxx.pid ] && echo "ok"), raise_on_non_zero_exit: false
# resp => ""
于 2014-12-11T16:02:39.150 回答
0

因此,我所做的工作是开始在 repo 中添加我称之为 Capistrano 实用程序脚本的内容。然后 capistrano 运行这些脚本。所有的脚本都是一个 grep 的包装器和一些逻辑,如果返回为空,则输出一些东西。

卡皮斯特拉诺代码:

namespace :utils do
  task :log_grep, :str, :file, :save_to do |t,args|
    command_args = "#{args[:str]} #{args[:file]}"
    outs = {}
    on roles(:app), in: :parallel do
      outs[host.hostname] = capture(:ruby, "#{fetch(:deploy_to)}/current/bin/log_grep.rb #{args[:str]} #{args[:file]}")
    end

    file = args[:save_to]
    file ||= 'log_grep_output'
    File.open(file, 'w') do |fh|
      outs.each do |host,out|
        s = "#{host} -- #{out}\n"
        fh.write(s)
      end
    end
  end
end

Ruby 脚本 log_grep.rb:

a = `zgrep #{ARGV[0]} #{ARGV[1]}`
if a.empty?
  puts 'Nothing Found'
else
  puts a
end
于 2014-09-02T07:32:53.497 回答