Come riavviare completamente lo script dall'interno dello script stesso


22

Sto impostando uno script di shell con menu e sottomenu, opzioni, ecc. Ma su ogni menu / sottomenu / etc, ho bisogno di una scelta "Torna al menu principale".

Ho già impostato il menu e funziona bene, ma ho bisogno di un modo per riavviare lo script da zero, ripristinare tutte le variabili ecc.

O un modo per uscire dallo script corrente e riavviarlo.

Ho provato a fare questo:

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

Ma questo avvia il "nuovo" script all'interno del "vecchio" script, quindi quando esco dal "nuovo" script, ritorna al "vecchio" script (se questo ha senso). È una sceneggiatura all'interno di una specie di sceneggiatura.

Qualcuno ha idea di come riavviarlo completamente?


Dovrebbe essere $ScriptLoccomunque: ./ScriptLoccerca uno script con quel nome nella directory corrente.
poolie,

Risposte:



10

Puoi usare qualcosa del genere:

$(basename $0) && exit

$(basename $0)creerà una nuova istanza dello script corrente e exituscirà dall'istanza corrente dello script.

Ecco uno script di test che evidenzia il metodo sopra:

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

Se non usi export count=0(che fa countdi essere una variabile d'ambiente) e usi solo count=0(che rende contuna variabile di script locale), allora lo script non si fermerà mai.


&& exitverrà chiuso solo se lo script ha esito positivo. Quindi, se ad esempio lo script non è eseguibile o presenta un errore di sintassi, è probabile che questo giri.
poolie,

Aggiunto ./ al basename - altrimenti una soluzione meravigliosa - davvero bello, def a +1.
Lefty G Balogh

4

Ottenere in modo affidabile lo script attualmente in esecuzione è più difficile di quanto si pensi. Vedi http://mywiki.wooledge.org/BashFAQ/028 .

Invece, potresti fare qualcosa del genere:

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

Fondamentalmente, esegui la funzione main_menu in una subshell, quindi se esci da main_menu o da uno dei sottomenu, esci dalla subshell, non dalla shell principale. lo stato di uscita 255 viene scelto qui per indicare "vai di nuovo". Qualsiasi altro stato di uscita uscirà dal ciclo altrimenti infinito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.