web-dev-qa-db-fra.com

ruby commande du système vérifier le code de sortie

J'ai un groupe 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 se termine 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 abouti. Sinon, une erreur ou une erreur de ce type est générée.

Est-ce possible?

J'ai essayé quelque chose dans le sens de ceci et cela n'a pas fonctionné 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
101
user1530318

De la documentation :

le système retourne true si la commande donne un statut de sortie nul, false pour un statut de sortie non nul. Renvoie 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
158
Stefan

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

Quelques méthodes utiles du $? objet:

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

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

Donc

system( "foo" ) or exit

ou

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

devrait fonctionner et sont raisonnablement concis.

24
Neil Slater

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

exit_code = system("Ruby test.rb")

Rappelez-vous que chaque appel system ou son équivalent, qui inclut la méthode backtick, génère un nouveau shell, il est donc impossible de capturer le résultat d'un environnement précédent. Dans ce cas exit_code est true si tout a fonctionné, nil sinon.

Le popen3 La commande fournit plus de détails de bas niveau.

6
tadman

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

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

Le second appel ne sera pas exécuté si le premier échoue.

Vous pouvez envelopper ceux-ci dans un if () pour vous donner un contrôle de flux:

if (
  system("VBoxManage createvm --name test1") && 
  system("Ruby test.rb")
) 
  # do something
else
  # do something with $?
end
4
the Tin Man