125 votes

ruby system command check exit code

J'ai un tas d'appels système dans ruby tels que les suivants et je veux vérifier leurs codes de sortie simultanément afin que mon script sorte si cette commande échoue.

system("VBoxManage createvm --name test1")
system("ruby test.rb")

Je veux quelque chose comme

system("VBoxManage createvm --name test1", 0) <-- où le deuxième paramètre vérifie le code de sortie et confirme que cet appel système a réussi, et sinon, il lève une erreur ou fait quelque chose de ce genre.

Est-ce que c'est possible ?

J'ai essayé quelque chose comme ça et ça n'a pas marché non plus.

system("ruby test.rb")
system("echo $?")

ou

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end

188voto

Stefan Points 23363

De la documentation :

retours de systèmes true si la commande donne un statut de sortie nul, false pour un statut de sortie non nul. Retourne nil si l'exécution de la commande échoue.

system("unknown command")     #=> nil
system("echo foo")            #=> true
system("echo foo | grep bar") #=> false

En outre,

Un statut d'erreur est disponible dans $? .

system("VBoxManage createvm --invalid-option")

$?             #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus  #=> 2

52voto

Houcheng Points 488

Pour moi, je préfère utiliser `` pour appeler les commandes du shell et vérifier $ ? pour obtenir le statut du processus. Le $ ? est un objet d'état du processus, vous pouvez obtenir les informations sur le processus de la commande à partir de cet objet, notamment : le code d'état, l'état d'exécution, le pid, etc.

Quelques méthodes utiles de l'objet $ ?

   $?.exitstatus => return error code    
   $?.success? => return true if error code is 0, otherwise false
   $?.pid => created process pid

34voto

Neil Slater Points 11193

system renvoie à false si la commande a un code de sortie non nul, ou nil s'il n'y a pas de commande.

Par conséquent,

system( "foo" ) or exit

ou

system( "foo" ) or raise "Something went wrong with foo"

devraient fonctionner, et sont raisonnablement concises.

7voto

tadman Points 70178

Vous ne capturez pas le résultat de votre system où le code de résultat est renvoyé :

exit_code = system("ruby test.rb")

Souvenez-vous de chaque system ou équivalent, qui inclut la méthode backtick, génère un nouveau shell, il n'est donc pas possible de capturer le résultat de l'environnement d'un shell précédent. Dans ce cas exit_code es true si tout s'est bien passé, nil autrement.

El popen3 fournit plus de détails de bas niveau.

6voto

the Tin Man Points 69148

Une façon de le faire est de les enchaîner en utilisant and ou && :

system("VBoxManage createvm --name test1") and system("ruby test.rb")

Le deuxième appel ne sera pas exécuté si le premier échoue.

Vous pouvez les envelopper dans un if () pour vous permettre de contrôler le flux :

if (
  system("VBoxManage createvm --name test1") && 
  system("ruby test.rb")
) 
  # do something
else
  # do something with $?
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X