Comment redémarrer complètement le script depuis l'intérieur du script lui-même


22

Je mets en place un script shell avec des menus et sous-menus, des options, etc. Mais sur chaque menu / sous-menu / etc, j'ai besoin d'un choix "Retour au menu principal".

J'ai déjà configuré le menu et cela fonctionne bien, mais j'ai besoin d'un moyen de redémarrer simplement le script à partir de zéro, de réinitialiser toutes les variables, etc., etc.

Ou un moyen de quitter le script actuel et de le redémarrer.

J'ai essayé de faire ça:

ScriptLoc=$(readlink -f "$0")
./ScriptLoc

Mais cela démarre le "nouveau" script à l'intérieur de l '"ancien" script, donc quand je quitte le "nouveau" script, il revient au "vieux" script (si cela a un sens). C'est un script dans une sorte de script.

Quelqu'un a une idée de comment le redémarrer complètement?


Cela devrait être de $ScriptLoctoute façon: ./ScriptLocrecherche un script de ce nom dans le répertoire courant.
poolie

Réponses:



10

Vous pouvez utiliser quelque chose comme ceci:

$(basename $0) && exit

$(basename $0)va créer une nouvelle instance du script en cours et exitquittera l'instance actuelle du script.

Voici un script de test qui met en évidence la méthode ci-dessus:

#!/bin/bash

if ! [[ $count =~ ^[0-9]+$ ]] ; then
    export count=0
fi

echo $count

if [ $count -le 10 ]; then
    count=$(echo "$count+1" | bc)   
    ./$(basename $0) && exit #this will run if started from the same folder
fi

echo "This will be printed only when the tenth instance of script is reached"

Si vous n'utilisez pas export count=0(qui font countpour être une variable d'environnement) et utilisez seulement count=0(qui font contune variable de script locale), alors le script ne s'arrêtera jamais.


&& exitne se fermera que si le script réussit. Donc, si par exemple le script n'est pas exécutable ou a une erreur de syntaxe, cela risque de tourner.
poolie

Ajouté ./ au nom de base - sinon une belle solution - vraiment sympa, def a +1.
Lefty G Balogh

4

Obtenir de manière fiable le script en cours d'exécution est plus difficile que vous ne le pensez. Voir http://mywiki.wooledge.org/BashFAQ/028 .

Au lieu de cela, vous pouvez faire quelque chose comme ceci:

main_menu() { 
    printf '1. Do something cool\n'
    printf '2. Do something awesome\n'
    : ... etc
}

some_sub_sub_menu() {
    ...
    printf 'X. Return to main menu\n'
    ...
    if [[ $choice = [Xx] ]]; then
        exit 255
    fi
}

while true; do
    (main_menu)
    res=$?
    if (( res != 255 )); then
        break
    fi
done

Fondamentalement, vous exécutez la fonction main_menu dans un sous-shell, donc si vous quittez le main_menu, ou l'un des sous-menus, vous quittez le sous-shell, pas le shell principal. l'état de sortie 255 est choisi ici pour signifier "recommencer". Tout autre état de sortie sortira de la boucle par ailleurs infinie.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.