2011-01-24 7 views
7

¿Hay alguna manera de capturar un error de "comando no encontrado" en un script de Ruby? Por ejemplo, dada:¿Captura errores de "comando no encontrado" de los apoyos de Ruby?

output = `foo` 

Cómo hacer yo trampa de la situación en la que foo no está instalado? Esperaba que podría rescue una excepción, pero esto no parece funcionar en 1.8.7. ¿Hay alguna forma diferente de llamar al subproceso que hará lo que yo quiero? ¿O hay un enfoque diferente?

actualización

Mis disculpas, se me olvidó mencionar un requisito oculto: yo preferiría que el intérprete no se escapa de la línea de comandos para el usuario (que puede contener datos sensibles), de ahí la excepción método de captura es preferido. Disculpas de nuevo por dejar esto fuera la primera vez.

+0

Una táctica que es útil cuando se necesita una característica específica, es para ejecutar una verificación previa, buscar la característica, o aplicación, o código primero, antes de intentar ejecutarlo. Diciendo 'which' foo'' o usando un par de pruebas de archivos para buscar la existencia del archivo más su ejecutabilidad, le dirá si es seguro proceder sin intentar el comando y fallar. Mejora la experiencia del usuario porque puede controlar la forma en que reacciona ante la funcionalidad faltante, y elige una ruta alternativa o notifica al usuario que no puede continuar porque falta algo. –

+0

De acuerdo, pero 'que 'foo'' no es multiplataforma, y ​​no podía pensar en una forma de plataforma cruzada para hacerlo, salvo intentarlo y detectar el error ... – kfb

Respuesta

13

¡Utilice el código de retorno!

irb(main):001:0> `date` 
=> "Mo 24. Jan 16:07:15 CET 2011\n" 
irb(main):002:0> $? 
=> #<Process::Status: pid=11556,exited(0)> 
irb(main):003:0> $?.to_i 
=> 0 
irb(main):004:0> `foo` 
(irb):4: command not found: foo 
=> "" 
irb(main):005:0> $?.to_i 
=> 32512 

http://corelib.rubyonrails.org/classes/Process/Status.html

Redirigir STDERR a STDOUT le dará la salida como valor de retorno en lugar de distensión que acaba de salir:

irb(main):010:0> `foo 2>&1` 
=> "sh: foo: not found\n" 
irb(main):011:0> $?.to_i 
=> 32512 
+0

¡Gracias! Sin embargo, olvidé mencionar un requisito adicional de no filtrar la línea de comando; si entiendo correctamente, esto todavía mostrará el mensaje de comando no encontrado para el usuario. – kfb

+0

Ejemplo agregado sobre cómo hacer esto a mi respuesta. –

+0

¡Funciona como un encanto! ¡Gracias! – kfb