Ruby on rails 卡皮斯特拉诺;Bash:忽略命令退出状态
我正在使用Capistrano运行远程任务。我的任务如下所示: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
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,你可以使用