J'écris des scripts en rubis et je dois interfacer avec du code non rubis via des commandes shell. Je sais qu'il y a au moins 6 différentes manières d'exécution des commandes shell Depuis de rubis, malheureusement, aucun de ceux-ci ne semble arrêter l'exécution lorsqu'une commande shell échoue.
Fondamentalement, je cherche quelque chose qui fait l'équivalent de: p> ... dans un script Bash. Idéalement, la solution susciterait une exception lorsque la commande échoue (c'est-à-dire en vérifiant une valeur de retour non nulle), peut-être avec STDERR comme message. Ce ne serait pas trop difficile à écrire, mais cela semble que cela devrait exister déjà. Y a-t-il une option que je ne trouve tout simplement pas? P> p>
4 Réponses :
Vous pouvez utiliser l'une des variables spéciales de Ruby. Le $? (analogue au même script shell var).
`ls` if $?.to_s == "0" # Ok to go else # Not ok end
Pourquoi utiliseriez-vous to_s code> pour comparer avec la chaîne
0 code>?
si $? == 0 code>
Je dirais même si $ ?. zéro? Code>
@Nakilon $ ?. zéro? Code> Soulevez le nométhodeurror
@ Mu-Ikjeon, vous ferez face à cela si vous n'avez pas encore appelé de sous-processus, car $? Code> est
nil code> depuis le début.
@Nakilon $? est le processus :: classe de statut. Met $ ?. Processus de classe :: Statut Code> La classe n'a pas de zéro? ' méthode. ruby-doc.org/core-2.2.0/process/status. HTML
@ Mu-ikjeon, oh tu as raison, bizarre. On dirait que le code d'erreur est dans $ ?. exitStatus code> Stackoverflow.com/a/38683399/322020
La meilleure façon de vérifier est si $ ?. Succès? Code> ruby-doc.org/core-2.2.0/process/status.html#method-i-success -3f . La façon dont je l'utilise est
quitte $ ?. to_i à moins que $ $ ?. Succès? Code>
$ ?. to_s retourne "PID 908 sortie 0" lorsque je l'exécute avec système ("Commande"), cela ne fonctionne donc pas. Cependant, système ("commandement") et également $ ?. Succès? Les deux rendent vrai ou faux selon qu'il y avait une erreur.
La manière la plus simple serait de créer une nouvelle fonction (ou de redéfinir un fichier existant) pour appeler le système () et de vérifier le code d'erreur.
quelque chose comme: p>
old_sys = system def system(...) old_system(...) if $? != 0 then raise :some_exception end
Ouais, c'était ce que je pensais quand j'ai dit "ne serait pas trop difficile d'écrire", mais cela semble-t-il déjà quelque chose qui aurait dû être résolu déjà, vous savez? Merci pour l'exemple.
Bien que, vous souhaiteriez augmenter code> au lieu de
lancer code>
FYI: L'alias lisible pour $? Code> est
$ enfant_status code>. Refs: docs.ruby-lang.org/fr/2.2. 0 / processus / status.html , ruby-doc.org/stdlib-2.5.0/libdoc/english/rdoc/english.html
minuscule un peu plus simple: vous n'avez pas besoin de vérifier afin que vous puissiez prendre une étape plus loin et faire: P> ... qui serait court-circuit et échoué sur une erreur (en plus d'être difficile à lire). P> ref: de ruby 2.0 doc pour System renvoie http: // www.ruby-doc.org/core-2.0.0/kernel.html#method-i-i-i-i-System p> p> $? code> w /
système code>, et puisque la commande que vous avez exécutée sera sortie sur
starr code > vous pouvez généralement juste juste une sortie non nulle plutôt que d'élever une exception avec une trace de pile laide:
système code> (bien que vrai de 1.8.7 aussi): P>
true code> si la commande donne un état de sortie zéro,
false code> pour statut de sortie non nul. P>
blockQuote>
Intéressant, j'aime ça. Pourriez-vous ajouter un lien à votre référence (la partie des documents rubis où vous l'avez trouvée)?
Ruby 2.6 ajoute un Exception: code > Argument
:
system('ctat nonexistent.txt', exception: true) # Errno::ENOENT (No such file or directory - ctat)