スクリプト自体の内部からスクリプトを完全に再起動する方法


22

メニューとサブメニュー、オプションなどを使用してシェルスクリプトを設定しています。ただし、各メニュー/サブメニューなどでは、「メインメニューに戻る」を選択する必要があります。

メニューは既に設定されており、正常に動作しますが、スクリプトをゼロから再起動する、すべての変数をリセットするなどの方法が必要です。

または、現在のスクリプトを終了して再起動する方法。

私はこれをやろうとしました:

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

しかし、それは「古い」スクリプト内の「新しい」スクリプトを開始するため、「新しい」スクリプトを終了すると、「古い」スクリプトに戻ります(それが意味をなす場合)。スクリプトのようなものの中のスクリプトです。

誰もそれを完全に再起動する方法を知っていますか?


それは$ScriptLocとにかくあるはずです:./ScriptLoc現在のディレクトリでその名前のスクリプトを探します。
プーリー

回答:



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スクリプトが成功した場合にのみ終了します。たとえば、スクリプトが実行可能でない場合、または構文エラーがある場合、これは単にスピンする可能性があります。
プーリー

./をベース名に追加-そうでなければ美しいソリューション-本当にいい、def a +1。
レフティGバログ

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が選択され、「再び行く」ことを意味します。その他の終了ステータスは、無限ループから抜け出します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.