So starten Sie das Skript vollständig aus dem Skript heraus neu

22

Ich richte ein Shell-Skript mit Menüs und Untermenüs, Optionen usw. ein. In jedem Menü / Untermenü / usw. benötige ich jedoch die Option "Zurück zum Hauptmenü".

Ich habe bereits das Menü eingerichtet und es funktioniert gut, aber ich brauche eine Möglichkeit, das Skript einfach von Grund auf neu zu starten, alle Variablen zurückzusetzen usw. usw.

Oder eine Möglichkeit, das aktuelle Skript zu beenden und erneut zu starten.

Ich habe versucht, dies zu tun:

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

Aber das startet das "neue" Skript innerhalb des "alten" Skripts. Wenn ich das "neue" Skript beende, kehre ich zum "alten" Skript zurück (wenn das Sinn macht). Es ist ein Drehbuch in einem Drehbuch.

Hat jemand eine Idee, wie man es komplett neu startet?

Mondblüte
quelle
Das sollte $ScriptLocjedenfalls so sein: ./ScriptLocSucht nach einem Skript mit diesem Namen im aktuellen Verzeichnis.
Poolie

Antworten:

10

Sie können so etwas verwenden:

$(basename $0) && exit

$(basename $0)erstellt eine neue Instanz des aktuellen Skripts und beendet exitdie aktuelle Instanz des Skripts.

Hier ist ein Testskript, das die obige Methode hervorhebt:

#!/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"

Wenn Sie nicht verwenden export count=0(wodurch counteine Umgebungsvariable erstellt wird) und nur verwenden count=0(wodurch conteine lokale Skriptvariable erstellt wird), wird das Skript niemals angehalten.

Radu Rădeanu
quelle
&& exitwird nur beendet, wenn das Skript erfolgreich ist. Wenn das Skript beispielsweise nicht ausführbar ist oder einen Syntaxfehler aufweist, dreht sich dies wahrscheinlich nur.
Poolie
Dem Basisnamen ./ hinzugefügt - ansonsten eine schöne Lösung - wirklich nett, def a +1.
Lefty G Balogh
4

Es ist schwieriger, das Skript, das gerade ausgeführt wird, zuverlässig abzurufen, als Sie vielleicht denken. Siehe http://mywiki.wooledge.org/BashFAQ/028 .

Stattdessen können Sie Folgendes tun:

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

Grundsätzlich führen Sie die Funktion main_menu in einer Subshell aus. Wenn Sie also das main_menu oder eines der Submenüs verlassen, verlassen Sie die Subshell und nicht die Mainshell. Der Beendigungsstatus 255 wird hier als "wieder gehen" ausgewählt. Jeder andere Beendigungsstatus löst sich aus der sonst unendlichen Schleife.

geirha
quelle