Capistrano&Bash:忽略命令退出状态

nic*_*des 48 ruby bash capistrano ruby-on-rails

我正在使用Capistrano运行远程任务.我的任务看起来像这样:

task :my_task do
  run "my_command"
end
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果my_command退出状态!= 0,那么Capistrano认为它失败并退出.当退出状态不为0时,如何在退出时让capistrano继续运行?我已经改变my_commandmy_command;echo它并且它有效,但感觉就像一个黑客.

mth*_*ley 77

最简单的方法是将true追加到命令的末尾.

  task :my_task do
    run "my_command"
  end
Run Code Online (Sandbox Code Playgroud)

  task :my_task do
    run "my_command; true"
  end
Run Code Online (Sandbox Code Playgroud)

  • 不知道capistano是什么,但由于与bash相同的问题,我找到了自己的方式.然后你可以使用"my_command || true"而不是"my_command; true" (12认同)

Cir*_*yon 37

对于Capistrano 3,您可以(如此处所示)使用以下内容:

execute "some_command.sh", raise_on_non_zero_exit: false
Run Code Online (Sandbox Code Playgroud)


mrf*_*lip 6

+ grep +命令根据它找到的内容退出非零.在您关心输出但不介意它是否为空的用例中,您将默默地丢弃退出状态:

run %Q{bash -c 'grep #{escaped_grep_command_args} ; true' }
Run Code Online (Sandbox Code Playgroud)

通常情况下,我认为第一个解决方案就好了 - 我会让它自己成为文件:

cmd = "my_command with_args escaped_correctly"
run %Q{bash -c '#{cmd} || echo "Failed: [#{cmd}] -- ignoring."'}
Run Code Online (Sandbox Code Playgroud)


Sar*_*Mei 5

如果您希望使用退出代码执行不同的操作,则需要修补Capistrano代码; 如果退出状态不为零,则硬编码引发异常.

这是lib/capistrano/command.rb的相关部分.以if (failed... 开头的行是重要的一行.基本上它表示如果有任何非零返回值,则引发错误.

# Processes the command in parallel on all specified hosts. If the command
# fails (non-zero return code) on any of the hosts, this will raise a
# Capistrano::CommandError.
def process!
  loop do
    break unless process_iteration { @channels.any? { |ch| !ch[:closed] } }
  end

  logger.trace "command finished" if logger

  if (failed = @channels.select { |ch| ch[:status] != 0 }).any?
    commands = failed.inject({}) { |map, ch| (map[ch[:command]] ||= []) << ch[:server]; map }
    message = commands.map { |command, list| "#{command.inspect} on #{list.join(',')}" }.join("; ")
    error = CommandError.new("failed: #{message}")
    error.hosts = commands.values.flatten
    raise error
  end

  self
end
Run Code Online (Sandbox Code Playgroud)


Bes*_*esi 5

我发现最简单的选择是:

run "my_command || :"
Run Code Online (Sandbox Code Playgroud)

注意::是 NOP 命令,因此退出代码将被忽略。