Ответ 1
Самый простой способ - просто добавить true в конец вашей команды.
task :my_task do
run "my_command"
end
становится
task :my_task do
run "my_command; true"
end
Я использую Capistrano для запуска удаленной задачи. Моя задача выглядит так:
task :my_task do
run "my_command"
end
Моя проблема в том, что если my_command
имеет статус выхода!= 0, то Капистрано считает, что он не прошел и выходит. Как я могу заставить capistrano продолжать работу при выходе, когда статус выхода не равен 0? Я изменил my_command
на my_command;echo
, и он работает, но он похож на хак.
Самый простой способ - просто добавить true в конец вашей команды.
task :my_task do
run "my_command"
end
становится
task :my_task do
run "my_command; true"
end
Для Capistrano 3 вы можете (как предложено здесь) использовать следующее:
execute "some_command.sh", raise_on_non_zero_exit: false
Команда + grep + выходит за пределы нуля, основываясь на том, что она находит. В том случае, когда вы заботитесь о выходе, но не возражаете, если он пуст, вы спокойно отмените состояние выхода:
run %Q{bash -c 'grep #{escaped_grep_command_args} ; true' }
Как правило, я думаю, что первое решение просто прекрасное - я сделаю это сам документа tho:
cmd = "my_command with_args escaped_correctly"
run %Q{bash -c '#{cmd} || echo "Failed: [#{cmd}] -- ignoring."'}
Вам нужно будет исправить код 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 "my_command || :"
Примечание: :
- это команда NOP, поэтому код выхода просто игнорируется.
Я просто перенаправляю STDERR и STDOUT на /dev/null, поэтому ваш
run "my_command"
становится
run "my_command > /dev/null 2> /dev/null"
это работает для стандартных инструментов unix довольно хорошо, где, скажем, cp или ln могут выйти из строя, но вы не хотите останавливать развертывание при таком сбое.
Я не уверен, какую версию они добавили, но мне нравится обращаться с этой проблемой, используя raise_on_non_zero_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
Вот где эта функция реализована в драгоценном камне. https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94