web-dev-qa-db-fra.com

Comment redémarrer complètement le script depuis l'intérieur du script

Je prépare un script Shell avec des menus et des sous-menus, des options, etc. Mais sur chaque menu/sous-menu/etc., il me faut 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 le script à partir de zéro, de réinitialiser toutes les variables, etc.

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

J'ai essayé de faire ceci:

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

Mais cela commence le "nouveau" script à l'intérieur de "l'ancien" script. Ainsi, lorsque je quitte le "nouveau" script, il retourne à "l'ancien" script (si cela a un sens). C'est un script dans un genre de script.

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

19
Moonbloom

Oui faire

exec "$ScriptLoc"

La exec commande intégrée de bash remplace le programme actuel par un nouveau.

20
poolie

Vous pouvez utiliser quelque chose comme ceci:

$(basename $0) && exit

$(basename $0) va créer une nouvelle instance du script en cours et exit va sortir de 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 fait de count une variable d'environnement) et que vous utilisez uniquement count=0 (qui fait de cont une variable de script locale), le script ne s'arrêtera jamais.

9
Radu Rădeanu

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 pourriez 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

En gros, vous exécutez la fonction main_menu dans un sous-shell. Par conséquent, si vous quittez le menu main_menu, ou l’un des sous-menus, vous quittez le sous-shell, et non le shell principal. le statut de sortie 255 est choisi ici pour signifier "repart". Tout autre statut de sortie sortira de la boucle sinon infinie.

4
geirha