2011-01-24 4 views
7

Existe-t-il un moyen de capturer une erreur «commande non trouvée» dans un script Ruby? Par exemple, étant donné:Capture des erreurs "command not found" des backticks de Ruby?

output = `foo` 

Comment puis-je piéger la situation où foo n'est pas installé? Je m'attendais à ce que je pourrais rescue une exception, mais cela ne semble pas fonctionner sur 1.8.7. Existe-t-il une manière différente d'appeler le sous-processus qui fera ce que je veux? Ou y a-t-il une approche différente?

Mise à jour

Mes excuses, j'oublié de mentionner une exigence cachée: Je préférerais que l'interprète ne fuit pas la ligne de commande à l'utilisateur (il peut contenir des données sensibles), donc pourquoi l'exception méthode de capture est préférée. Encore des excuses pour avoir laissé ça la première fois.

+0

Une tactique qui est utile lorsque vous avez besoin d'une fonctionnalité spécifique, est Pour exécuter un contrôle en amont, recherchez d'abord la fonctionnalité, ou l'application, ou le code, avant d'essayer de l'exécuter. Dire 'quel' foo'' ou en utilisant un couple de tests de fichiers pour rechercher l'existence du fichier plus son exécutabilité, vous dira s'il est sûr de procéder sans réellement tenter la commande et échouer. Cela améliore l'expérience utilisateur, car vous pouvez contrôler la façon dont vous réagissez à la fonctionnalité manquante et choisir un autre itinéraire, ou informer l'utilisateur que vous ne pouvez pas continuer car il manque quelque chose. –

+0

D'accord, mais 'qui 'foo'' n'est pas multi-plateforme, et je ne pouvais pas penser à une façon multi-plateforme pour le faire autrement que pour l'essayer et attraper l'erreur ... – kfb

Répondre

13

Utilisez le code de retour!

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

Rediriger STDERR à STDOUT vous donnera la sortie en tant que valeur de retour au lieu de ballonnements, il vient de sortir:

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

Merci! Cependant, j'ai oublié de mentionner une exigence supplémentaire de ne pas fuir la ligne de commande; si je comprends bien cela montrerait toujours le message de commande non trouvé à l'utilisateur. – kfb

+0

Ajout d'un exemple sur la façon de faire cela pour ma réponse. –

+0

Fonctionne comme un charme! Merci! – kfb

Questions connexes