Capistrano & Bash: ignore team exit status

I use Capistrano to run a remote task. My task looks like this:

task :my_task do run "my_command" end 

My problem is that if my_command has exit status! = 0, then Kapistrano considers that it did not pass and leaves. How can I make capistrano continue to work on exit when the exit status is not 0? I changed my_command to my_command;echo and it works, but it looks like a hack.

+46
ruby bash ruby-on-rails capistrano
Apr 17 '09 at 2:35
source share
7 answers

The easiest way is to simply add true to the end of your command.

  task :my_task do run "my_command" end 

becomes

  task :my_task do run "my_command; true" end 
+75
Aug 25 '09 at 14:19
source share

For Capistrano 3, you can (as suggested here ) use the following:

 execute "some_command.sh", raise_on_non_zero_exit: false 
+29
May 2 '14 at 8:49
source share

The + grep + command goes beyond zero based on what it finds. In the case when you care about the exit, but do not mind if it is empty, you will quietly cancel the exit state:

 run %Q{bash -c 'grep #{escaped_grep_command_args} ; true' } 

As a rule, I think the first solution is just fine - I will do this myself of the tho document:

 cmd = "my_command with_args escaped_correctly" run %Q{bash -c '#{cmd} || echo "Failed: [#{cmd}] -- ignoring."'} 
+7
Apr 21 '09 at 19:09
source share

You will need to fix the Capistrano code if you want it to do different things with exit codes; it is hardcoded to throw an exception if the exit status is non-zero.

Here is the relevant part of lib / capistrano / command.rb. The line starting with if (failed ... is important. Basically, it says that if there are non-zero return values, throw an error.

 # 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 
+5
Apr 17 '09 at 4:57
source share

I find the easiest way to do this:

 run "my_command || :" 

Note:: is a NOP command, so the exit code is simply ignored.

+4
Jul 11 '12 at 8:17
source share

I just redirect STDERR and STDOUT to / dev / null, so your

 run "my_command" 

becomes

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

this works for standard unix tools pretty well, where, say, cp or ln might fail, but you don't want to stop the deployment if that crashes.

+2
Apr 17 '09 at 5:17
source share

I'm not sure which version they added, but I like to handle this problem using 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 

That's where this feature is implemented in the gem. https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94

0
Aug 21 '17 at 23:58
source share



All Articles