Como reiniciar completamente o script de dentro do próprio script

15

Estou configurando um shell script com menus e sub-menus, opções, etc. Mas em cada menu / submenu / etc, eu preciso de uma opção "Volte para o menu principal".

Eu já tenho o menu configurado e funciona bem, mas eu preciso de uma maneira de simplesmente reiniciar o script a partir do zero, redefinir todas as variáveis etc etc

Ou uma maneira de sair do script atual e iniciá-lo novamente.

Eu tentei fazer isso:

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

Mas isso inicia o script "novo" dentro do script "antigo", então quando saio do script "novo", ele volta para o script "antigo" (se isso faz algum sentido). É um script dentro de um script de coisas.

Alguém tem uma ideia de como reiniciá-lo completamente?

    
por Moonbloom 11.10.2013 / 18:01

3 respostas

16

Sim, faça

exec "$ScriptLoc"

O exec bash comando substitui o programa atual por um novo.

    
por poolie 12.10.2013 / 01:47
5

Você pode usar algo assim:

$(basename $0) && exit

$(basename $0) criará uma nova instância do script atual e exit sairá da instância atual do script.

Aqui está um script de teste que destaca o método acima:

#!/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 você não usar export count=0 (o que torna count uma variável de ambiente) e usar apenas count=0 (o que torna cont uma variável de script local), o script nunca será interrompido. / p>     

por Radu Rădeanu 11.10.2013 / 18:15
4

A obtenção confiável do script que está sendo executado é mais difícil do que você imagina. Consulte o link .

Em vez disso, você poderia fazer algo assim:

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

Basicamente, você executa a função main_menu em um subshell, então se você sair do main_menu ou de qualquer um dos submenus, você sai do subshell, não do shell principal. O status de saída 255 é escolhido aqui para significar "ir novamente". Qualquer outro status de saída sairá do loop infinito.

    
por geirha 11.10.2013 / 21:59