Cara me-restart skrip sepenuhnya dari dalam skrip itu sendiri

22

Saya sedang menyiapkan skrip shell dengan menu dan sub menu, opsi, dll. Tetapi pada setiap menu / submenu / dll, saya memerlukan pilihan "Kembali ke menu utama".

Saya sudah menyiapkan menu dan berfungsi dengan baik, tetapi saya perlu cara untuk memulai kembali skrip dari awal, mengatur ulang semua variabel dll.

Atau cara untuk keluar dari skrip saat ini dan mulai lagi.

Saya sudah mencoba melakukan ini:

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

Tapi itu memulai skrip "baru" di dalam skrip "lama", jadi ketika saya keluar dari skrip "baru", ia kembali ke skrip "lama" (jika itu masuk akal). Itu adalah skrip di dalam skrip semacam itu.

Adakah yang tahu cara me-restart sepenuhnya?

Moonbloom
sumber
$ScriptLocBagaimanapun juga harusnya : ./ScriptLocmencari skrip dengan nama itu di direktori saat ini.
poolie

Jawaban:

22

Ya, lakukan

exec "$ScriptLoc"

Perintah execbash builtin menggantikan program saat ini dengan yang baru.

poolie
sumber
10

Anda dapat menggunakan sesuatu seperti ini:

$(basename $0) && exit

$(basename $0)akan membuat turunan baru dari skrip saat ini dan exitakan keluar dari turunan skrip saat ini.

Berikut ini skrip pengujian yang menyoroti metode di atas:

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

Jika Anda tidak menggunakan export count=0(yang menjadikannya countvariabel lingkungan) dan hanya menggunakan count=0(yang membuat contvariabel skrip lokal), maka skrip tidak akan pernah berhenti.

Radu Rădeanu
sumber
&& exitakan keluar hanya jika skrip berhasil. Jadi jika misalnya skrip tidak dapat dieksekusi atau memiliki kesalahan sintaksis, ini kemungkinan hanya berputar.
poolie
Ditambahkan ./ ke nama kecil - jika tidak solusi yang bagus - sangat bagus, def +1.
Lefty G Balogh
4

Andal mendapatkan skrip yang saat ini dieksekusi lebih sulit daripada yang Anda bayangkan. Lihat http://mywiki.wooledge.org/BashFAQ/028 .

Sebaliknya, Anda bisa melakukan sesuatu seperti ini:

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

Pada dasarnya, Anda menjalankan fungsi main_menu dalam subkulit, jadi jika Anda keluar dari main_menu, atau salah satu dari sub menu, Anda keluar dari subkulit, bukan pada shell utama. status keluar 255 dipilih di sini berarti "pergi lagi". Status keluar lain apa pun akan keluar dari loop yang tidak terbatas.

geirha
sumber