Serveur Ubuntu 18.04 + LXDE. Je ne peux pas comprendre ce script bash.
Voici mon script "start" (avec numérotation des lignes):
#!/bin/bash
reply=Sudo mount 192.168.0.2:/home/dk/NFS /home/dk/NFS
if $reply == 0
then
echo "NFS mounted OK"
else
echo "Mounting NFS failed: $reply"
fi
reply=Sudo mount LABEL="60GB" /home/dk/60GB
if $reply == 0
then
echo "60GB mounted OK"
else
echo "Mounting 60GB failed: $reply"
fi
exit 0
C'est le résultat de l'exécuter:
$ ./scripts/start
mount: only root can do that
./start: line 3: ==: command not found
Mounting NFS failed:
mount: only root can do that
./start: line 11: ==: command not found
Mounting 60GB failed:
$
Sudo
avant le mount
?if
comme une commande?$reply
?Eh bien, vous n'attribuez pas correctement la sortie d'une commande. Devrait être:
reply=$(Sudo mount 192.168.0.2:/home/dk/NFS /home/dk/NFS)
Cela s'appelle substitution de commande. Parfois, vous le voyez dans l'ancienne syntaxe Bourne Shell avec des guillemets arrières au lieu de $(...)
, mais ce n'est plus recommandé de nos jours car les guillemets arrières ne peuvent pas être imbriqués facilement, alors que vous pouvez imbriquer $( cmd1 $(cmd2))
.
Pourquoi n'a-t-il pas considéré le "si" comme une commande?
Si les instructions fonctionnent avec des commandes, mais que vous donnez la variable $reply
, qui n'existe que temporairement (voir réponse plus loin dans cette réponse), elle n'existe donc que pour l'environnement de la commande mount
name__, mais le shell qui exécute le script n'en sait rien - il n'en a rien. t existent. Pour comparer les chaînes, utilisez [
, et oui, cette commande est également appelée test
name__. Alors faites
if test "$reply" == 0
Voir les citations? C'est important, sinon, s'il y a des espaces, Shell étendra la variable à deux ou plusieurs entités distinctes et non à une seule.
Mais si vous voulez vérifier le statut de sortie de la commande, il suffit de faire
if mount 192.168.0.2:/home/dk/NFS /home/dk/NFS
Voir non Sudo
name__? En effet, il est généralement redondant d’utiliser plusieurs fois Sudo dans un script. Appelez simplement le script lui-même avec Sudo et toutes les commandes auront le privilège root.
Je dirais aussi que echo est redondant car la commande mount peut déjà imprimer des erreurs sur le terminal, mais si vous voulez un message personnalisé, vous pouvez le faire.
if mount 192.168.0.2:/home/dk/NFS /home/dk/NFS 1> /dev/null
then
echo "Success"
else
echo "Fail"
fi
En raison de 1>
, la sortie normale est supprimée (en fait redirigée vers /dev/null
surtout à cette fin), mais des erreurs s'afficheront si quelque chose ne va pas.
Pourquoi a-t-il ignoré le "Sudo" avant le "montage"?
En ce qui concerne la raison pour laquelle vous obtenez un message d'erreur, c'est parce que le formulaire
reply=Sudo mount 192.168.0.2:/home/dk/NFS /home/dk/NFS
est traité comme envvariable=value command arg1 arg2
, c’est-à-dire que vous mettez la variable result
avec la valeur Sudo
dans l’environnement de la commande mount
name__. La commande le saura, mais une fois la commande terminée, la variable sera également partie.
Pourquoi n'a-t-il pas imprimé la valeur (non nulle) de $ réponse?
Parce que reply
ne stocke pas le statut de sortie comme expliqué précédemment. Il y a en fait une variable pour celle fournie par Shell déjà, $?
alors utilisez-la comme
if [ $? -eq 0 ]
Rincez et répétez les suggestions relatives aux autres instructions de votre script.
Bonne chance
En plus de la bonne réponse de Sergiy, vous pouvez envisager d'utiliser les listes AND et OR pour vérifier rapidement si une commande renvoie un état de sortie égal à zéro (réussi) ou non, par exemple
command && echo "command succeeded" || echo "command failed"
Voici un extrait de man bash
:
Les listes AND et OR sont des séquences d'un ou de plusieurs pipelines séparés par les opérateurs de contrôle
&&
et||
, respectivement. Les listes AND et OR sont exécutées avec une associativité à gauche. Une liste AND a la formecommand1 && command2
commande2 est exécutée si, et seulement si, commande1 renvoie un état de sortie égal à zéro.
Une liste OR a la forme
command1 || command2
commande2 est exécutée si et seulement si commande1 renvoie un état de sortie différent de zéro. Le statut de retour des listes AND et OR correspond au statut de sortie de la dernière commande exécutée dans la liste.
Vous pouvez les combiner et également voir le statut de sortie si vous le souhaitez, avec votre exemple tel que:
Sudo mount 192.168.0.2:/home/dk/NFS /home/dk/NFS && \
echo "NFS mounted OK" || echo "Mounting NFS failed: $?"
Problèmes avec votre script:
`
pour la commande Sudo mount ..
. Pour exécuter une commande, vous devez la remettre entre guillemets `command`
ou $(command)
. Vous pouvez également capturer la valeur de retour du script en utilisant $?
.Si la construction de la boucle était incorrecte
if [ $var -eq/-lt/-gt "string"/number ]
then
echo "...."
else
echo "..."
fi; <=== Most users miss this.
** Script édité **
#!/bin/bash
reply=`Sudo mount 192.168.0.2:/home/dk/NFS /home/dk/NFS`
if [ $reply -eq "0" ]
then
echo "NFS mounted OK"
else
echo "Mounting NFS failed: $reply"
fi;
reply=`Sudo mount LABEL="60GB" /home/dk/60GB`
if[ $reply -eq "0" ]
then
echo "60GB mounted OK"
else
echo "Mounting 60GB failed: $reply"
fi;
exit 0