Ruby on rails 卡皮斯特拉诺;Bash:忽略命令退出状态

Ruby on rails 卡皮斯特拉诺;Bash:忽略命令退出状态,ruby-on-rails,ruby,bash,capistrano,Ruby On Rails,Ruby,Bash,Capistrano,我正在使用Capistrano运行远程任务。我的任务如下所示: task :my_task do run "my_command" end 我的问题是,如果My_命令具有退出状态!=0,则Capistrano认为它失败并退出。退出状态不是0时,如何使capistrano在退出时继续运行?我已将我的_命令更改为我的_命令;echo可以工作,但感觉像是黑客攻击。如果你想让Capistrano代码与退出代码做不同的事情,你需要对其进行修补;如果退出状态不是零,则硬编码会引发异常 下面是lib/c

我正在使用Capistrano运行远程任务。我的任务如下所示:

task :my_task do
  run "my_command"
end

我的问题是,如果
My_命令
具有退出状态!=0,则Capistrano认为它失败并退出。退出状态不是0时,如何使capistrano在退出时继续运行?我已将
我的_命令
更改为
我的_命令;echo
可以工作,但感觉像是黑客攻击。

如果你想让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
#在所有指定主机上并行处理该命令。如果
#在任何主机上失败(非零返回代码),这将引发
#Capistrano::CommandError。
def程序!
环道
中断,除非进程_迭代{@channels.any?{{| ch |!ch[:closed]}
结束
logger.trace“命令完成”如果是记录器
如果(failed=@channels.select{| ch | ch[:status]!=0})。有吗?

commands=failed.injection({}){| map,ch |(map[ch[:command]]| |=[])我只是将STDERR和STDOUT重定向到/dev/null,所以

run "my_command"
变成

run "my_command > /dev/null 2> /dev/null"

这对于标准的unix工具非常有效,比如说,cp或ln可能会失败,但您不想在出现这种故障时停止部署。

根据找到的内容,+grep+命令退出非零状态。在您关心输出但不介意输出是否为空的情况下,您将默默放弃退出状态:

run %Q{bash -c 'grep #{escaped_grep_command_args} ; true' }
通常情况下,我认为第一种解决方案很好——我会让它自己记录下来,如下所示:

cmd = "my_command with_args escaped_correctly"
run %Q{bash -c '#{cmd} || echo "Failed: [#{cmd}] -- ignoring."'}

最简单的方法是在命令末尾追加true

  task :my_task do
    run "my_command"
  end
变成

  task :my_task do
    run "my_command; true"
  end

我发现最简单的方法是:

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

对于Capistrano 3,您可以(根据建议)使用以下命令:

execute "some_command.sh", raise_on_non_zero_exit: false

我不确定他们添加此代码的版本,但我喜欢使用
raise\u on\u non\u zero\u exit来处理此问题

namespace :invoke do
  task :cleanup_workspace do
    on release_roles(:app), in: :parallel do
      execute 'sudo /etc/cron.daily/cleanup_workspace', raise_on_non_zero_exit: false
    end
  end
end
这就是gem中实现该特性的地方。

我不确定capistano是什么,但我找到了我的方法,因为bash也有同样的问题。然后你可以使用“my_command | | true”而不是“my_command;true”非常好的选项!我想这只适用于Capistrano 2,对于Capistrano 3,你可以使用