Як повністю перезапустити скрипт зсередини самого сценарію


22

Я встановлюю скрипт оболонки з меню та підменю, параметрами тощо. Але для кожного меню / підменю / тощо мені потрібен вибір "Повернутися до головного меню".

У мене вже налаштоване меню, і воно працює добре, але мені потрібен спосіб просто перезапустити скрипт з нуля, скинути всі змінні тощо.

Або спосіб вийти з поточного сценарію та запустити його заново.

Я намагався це зробити:

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

Але це запускає "новий" скрипт всередині "старого" сценарію, тому коли я виходжу з "нового" сценарію, він повертається до "старого" сценарію (якщо це має сенс). Це сценарій всередині сценарію.

У когось є ідея, як її повністю перезапустити?


Це має бути так $ScriptLocчи інакше: ./ScriptLocшукає сценарій цього імені у поточному каталозі.
poolie

Відповіді:



10

Ви можете використовувати щось подібне:

$(basename $0) && exit

$(basename $0)створить новий екземпляр поточного сценарію та exitвийде з екземпляра скрипту.

Ось тестовий сценарій, який висвітлює описаний вище метод:

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

Якщо ви не використовуєте export count=0(які перетворюються countна змінну середовища) і використовують лише count=0(які роблять contзмінну локального скрипту), то сценарій ніколи не зупиниться.


&& exitвийде лише у випадку успіху сценарію. Отже, якщо, наприклад, скрипт не виконується або є синтаксична помилка, це, ймовірно, просто повернеться.
poolie

Додано ./ до базового імені - інакше прекрасне рішення - дуже приємно, визначте +1.
Lefty G Balogh

4

Надійніше отримати сценарій, який зараз виконується, складніше, ніж ви могли подумати. Дивіться http://mywiki.wooledge.org/BashFAQ/028 .

Натомість ви можете зробити щось подібне:

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

В основному, ви запускаєте функцію main_menu в підклітині, тому якщо ви виходите з main_menu або будь-якого з підменю, ви виходите з допоміжної оболонки, а не з основної оболонки. тут вибрано статус виходу 255, щоб означати "йти знову". Будь-який інший статус виходу вирветься з нескінченного циклу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.