Cómo reiniciar completamente el script desde el propio script

22

Estoy configurando un script de shell con menús y submenús, opciones, etc. Pero en cada menú / submenú / etc., necesito la opción "Volver al menú principal".

Ya tengo el menú configurado y funciona bien, pero necesito una forma de reiniciar el script desde cero, restablecer todas las variables, etc.

O una forma de salir del script actual y comenzarlo de nuevo.

He intentado hacer esto:

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

Pero eso inicia el guión "nuevo" dentro del guión "antiguo", por lo que cuando salgo del guión "nuevo", vuelve al guión "antiguo" (si eso tiene sentido). Es un guión dentro de un tipo de guión.

¿Alguien tiene una idea de cómo reiniciarlo por completo?

Flor de luna
fuente
Eso debería ser de $ScriptLoctodos modos: ./ScriptLocbusca un script con ese nombre en el directorio actual.
Poolie

Respuestas:

10

Puedes usar algo como esto:

$(basename $0) && exit

$(basename $0)creará una nueva instancia del script actual y exitsaldrá de la instancia actual del script.

Aquí hay un script de prueba que destaca el método anterior:

#!/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 no usa export count=0(que hace countque sea una variable de entorno) y usa solo count=0(que hace que contuna variable de script local), el script nunca se detendrá.

Radu Rădeanu
fuente
&& exitsaldrá solo si el script tiene éxito. Entonces, si, por ejemplo, el script no es ejecutable o tiene un error de sintaxis, es probable que solo gire.
Poolie
Se agregó ./ al nombre base, de lo contrario, una solución hermosa, realmente agradable, def a +1.
Lefty G Balogh
4

Obtener de manera confiable el script que se está ejecutando actualmente es más difícil de lo que piensas. Ver http://mywiki.wooledge.org/BashFAQ/028 .

En cambio, podrías hacer algo como esto:

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

Básicamente, ejecuta la función main_menu en un subshell, por lo que si sale del main_menu, o de cualquiera de los submenús, sale del subshell, no del shell principal. El estado de salida 255 se elige aquí para significar "ir de nuevo". Cualquier otro estado de salida saldrá del bucle infinito.

geirha
fuente