2009-04-17 15 views
46

Estoy usando Capistrano ejecutar una tarea remota. Mi tarea es el siguiente:Capistrano & Bash: ignorar el estado de salida del comando

task :my_task do 
    run "my_command" 
end 

Mi problema es que si my_command tiene un estado de salida = 0, entonces Capistrano considera que fracasó y salidas!. ¿Cómo puedo hacer que el capistrano continúe cuando salga cuando el estado de salida no sea 0? Cambié my_command a my_command;echo y funciona, pero se siente como un truco.

Respuesta

75

La manera más simple es simplemente anexar verdadero al final de su comando.

task :my_task do 
    run "my_command" 
    end 

Se convierte en

task :my_task do 
    run "my_command; true" 
    end 
+12

No estoy seguro de qué es el capistano pero encontré mi camino debido al mismo problema con bash. Y luego puede usar "my_command || true" en lugar de "my_command; true" – Zitrax

5

Deberá parchar el código de Capistrano si desea que haga cosas diferentes con los códigos de salida; está codificado para generar una excepción si el estado de salida no es cero.

Aquí está la parte relevante de lib/capistrano/command.rb. La línea que comienza con if (failed ... es la más importante. Básicamente dice que si hay valores de retorno distintos de cero, genera un 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 
+0

Supongo que esto es solo para Capistrano 2, para Capistrano 3, puede usar [respuesta de Ciryon] (http: // stackoverflow.com/a/23424213/345959) – Smar

2

acabo redirigir STDERR y stdout a/dev/null, por lo que su

run "my_command" 

convierte

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

esto funciona para herramientas estándar de Unix bastante bien, donde, por ejemplo, cp o ln puede fallar, pero no desea detener el despliegue en tal falla.

7

El comando + grep + sale de cero en función de lo que encuentre. En el caso de uso en el que se preocupa por la salida, pero no le importa si está vacío, se le desecha el estado de salida en silencio:

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

Normalmente, creo que la primera solución es bien - Me hacer que se documente solo tho:

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

me parece la opción más sencilla de hacerlo:

run "my_command || :" 

Aviso: : es el comando NOP tan simplemente se ignora el código de salida.

30

Para Capistrano 3, puede (como se sugiere here) utilice la siguiente:

execute "some_command.sh", raise_on_non_zero_exit: false 
+1

funcionó para mí de la mejor manera. – khelll

+0

muy buena opción! – Aleksey

0

No estoy seguro de qué versión se añaden este código, pero me gusta el manejo de este problema utilizando 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 

Aquí es donde se implementa esa característica en la gema. https://github.com/capistrano/sshkit/blob/4cfddde6a643520986ed0f66f21d1357e0cd458b/lib/sshkit/command.rb#L94

Cuestiones relacionadas