J'ai un script et je souhaite obtenir la valeur de retour de ce script et le stocker dans une variable.
Toute aide est la bienvenue.
Merci d'avance.
#!/bin/bash HOST_NAME=$1 { echo "105" ; sleep 5; } | telnet $HOST_NAME 9761;
4 Réponses :
La variable ?
stocke toujours le code de sortie de la commande précédente.
Vous pouvez récupérer la valeur avec $?
.
Un peu de contexte: http://tldp.org/LDP/abs/ html / exit-status.html
La variable shell $?
stocke la valeur de retour, mais avec le client Linux telnet
cela peut ne pas être aussi utile que vous le pensez. Le client renverra 1
si l'hôte distant ferme la connexion (ou toute erreur distante ou réseau se produit) et 0
si le côté client local ferme la connexion avec succès. Le problème étant que de nombreux services sont écrits de manière à envoyer des données puis à fermer eux-mêmes la connexion TCP sans attendre le client:
$ telnet www.google.com 80 Trying 216.58.210.36... Connected to www.google.com. Escape character is '^]'. ^] telnet> quit Connection closed. $ echo $? 0
Même si le client envoie une commande au serveur pour quitter le flux TCP, cela entraîne toujours la fermeture de la connexion par le côté distant, avec le même résultat:
$ ssh ssh.tardis.ed.ac.uk "exit 5" THE TARDIS PROJECT | pubpubpubpubpubpubpubpubpub | Authorised access only $ echo $? 5
Donc, vous allez obtenir un 1 code> peu importe quoi vraiment. Si vous voulez la valeur de retour d'un script distant, c'est plus facile avec
ssh
comme ceci:
$ telnet mail.tardis.ed.ac.uk 25 Trying 193.62.81.50... Connected to isolus.tardis.ed.ac.uk. Escape character is '^]'. 220 isolus.tardis.ed.ac.uk ESMTP Postfix (Debian/GNU) QUIT 221 2.0.0 Bye Connection closed by foreign host. $ echo $? 1
Pour autant que je sache, la seule fois telnet retournerait zéro (c'est-à-dire succès) si vous vous échappez et tout à fait le client, comme ceci:
$ telnet time-b.timefreq.bldrdoc.gov 13 Trying 132.163.96.2... Connected to time-b-b.nist.gov. Escape character is '^]'. 58600 19-04-27 13:56:16 50 0 0 736.0 UTC(NIST) * Connection closed by foreign host. $ echo $? 1
J'espère que cela aide.
" La variable $? shell " Je sais que c'est difficile, mais $?
n'est pas le nom d'une variable, c'est la valeur de la variable ?
. Le préfixe $
est un opérateur unaire qui donne la valeur, comme je suis sûr que vous le savez. Pardon.
J'ai vu à la fois $ VAR
et VAR
utilisés dans différentes documentations, je pense que cela dépend du niveau d'expertise en programmation shell que le lecteur devrait avoir ...
Je l'ai également vu mal nommé ailleurs. Cela prête à confusion lors de l'utilisation de commandes telles que export
(qui est une commande très basique) et declare
où le nom de la variable est utilisé, non préfixé par $ code >. Je trouve qu'avec les débutants, il vaut mieux avoir raison sur le nom et exactement ce qu'est le
$
, sinon vous aurez des problèmes plus tard.
Pour éviter toute confusion, ne le pensez pas / n'en parlez pas comme une valeur de retour, pensez-y comme ce qu'il est - un état de sortie.
Dans la plupart des langages de programmation, vous pouvez capturer la valeur de retour d'une fonction en capturant ce que cette fonction retourne dans une variable, par exemple avec un langage de type C:
foo() { printf "35\n" return 7 } main() { local var foo var=$? }
la variable var
dans main ()
après avoir appelé foo ( )
contiendra la valeur 7
et 35
aura été imprimé sur stdout. En shell cependant avec un code similaire:
foo() { printf "35\n" return 7 } main() { local var var=$(foo) }
var
aura la valeur 35
et la variable intégrée non mentionnée $? qui contient toujours l'état de sortie de la dernière commande exécutée aura la valeur 7
. Si vous vouliez dupliquer le comportement C où 35 va vers stdout et var en contient 7, alors ce serait:
int foo() { printf("35\n"); return 7; } void main() { int var; var=foo(); }
Le fait que les fonctions shell utilisent le mot-clé return
pour signaler leur statut de sortie est déroutant au début si vous êtes habitué à d'autres langages basés sur Algol comme C mais s'ils utilisaient exit
alors cela mettrait fin à l'ensemble du processus, ils devaient donc utilisez quelque chose et il devient rapidement évident ce que cela signifie vraiment.
Ainsi, lorsque vous abordez les scripts et les fonctions du shell, utilisez les mots "sortie" et "état de sortie", et non "retour" que certaines personnes dans certains contextes feront assumer signifie l'une de ces 2 choses, et cela évitera toute confusion.
Btw pour éviter de rendre les choses encore plus compliquées, j'ai dit plus haut que $?
est une variable mais c'est vraiment la valeur du "paramètre spécial" ?
. Si vous voulez vraiment comprendre la différence dès maintenant, consultez https: //www.gnu.org/software/bash/manual/bash.html#Shell-Parameters pour une discussion sur les paramètres du shell qui inclut des "paramètres spéciaux" comme ?
et #
, des "paramètres de position" comme 1
et 2
, et des "variables" comme HOME
et var code > tel qu'utilisé dans mon script ci-dessus.
Bonne réponse. Il est probablement également intéressant de mentionner que le type de données de l'état de sortie est limité à un caractère non signé, contrairement à d'autres langages de programmation où une fonction peut renvoyer n'importe quel type de données
@ hek2mgl: ce n'est pas toute l'histoire. Là où il est vrai que le statut est le 8 bits de poids faible en C, la valeur de retour de wait (3)
et waitpid (3)
est un pid_t
type (souvent un unsigned int
mais dépendant de l'implémentation).
Salut Ed, merci beaucoup
Cela dépend de ce que vous entendez par valeur de retour .
Les processus (sur les systèmes de type UNIX) peuvent renvoyer à un shell un seul octet non signé comme état de sortie, ce qui donne une valeur dans la gamme 0-255. Par convention, zéro signifie succès et toute autre valeur indique un échec.
(Dans les langages de niveau inférieur, comme C, vous pouvez obtenir plus que ce statut de sortie, mais ce n'est pas visible dans bash
).
Le l'état de sortie de la dernière commande exécutée est stocké dans la variable ?
, vous pouvez donc obtenir sa valeur à partir de $?
, cependant puisque de nombreux programmes ne renvoient que 0 (cela a fonctionné) ou 1 (cela n'a pas fonctionné), ce n'est pas très utile.
Bash
conditionnels, comme if
et while
test en cas de succès (code de sortie de 0) ou d'échec (code de sortie de non-zéro):
var=$(some-command 2>&1)
Cependant ....
Si vous voulez dire que vous voulez obtenir la sortie du script, c'est une autre affaire. Vous pouvez le capturer en utilisant:
var=$(some-command)
Mais attendez, cela ne capture que la sortie normale, acheminée vers un flux appelé stdout
(descripteur de fichier 1), il ne capture pas les messages d'erreur que la plupart des programmes écrivent dans un flux appelé stderr
(descripteur de fichier 2). Pour capturer les erreurs également, vous devez rediriger le descripteur de fichier 2 vers le descripteur de fichier 1:
if some-command then echo "It worked" else echo "It didn't work" fi
Le texte de sortie est maintenant dans la variable var
. p>
Salut cDarke, Merci pour l'info.
Copie possible de Capture de l'état de sortie d'une commande ayant échoué dans un script shell
Pensez à utiliser ssh (mieux avec public-key-auth) pour exécuter des commandes à distance. Tout d'abord et surtout: aucun mot de passe en texte clair n'est utilisé. Deuxième gestion plus facile en raison de tous les avis de bienvenue ou de message du jour interactifs que telnet fait régulièrement. Troisièmement, exécution facile (plus) de scripts complets.