如何从脚本本身内部完全重新启动脚本


22

我正在设置带有菜单和子菜单,选项等的Shell脚本。但是在每个菜单/子菜单/等上,我都需要“返回主菜单”选项。

我已经设置了菜单,它可以正常工作,但是我需要一种方法从头开始重新启动脚本,重置所有变量等。

或者一种退出当前脚本并重新启动它的方法。

我尝试这样做:

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

但这会在“旧”脚本中启动“新”脚本,因此当我退出“新”脚本时,它会返回到“旧”脚本(如果有任何意义)。这是脚本内部的一种脚本。

任何人都知道如何完全重新启动它吗?


$ScriptLoc无论如何,这应该是:./ScriptLoc在当前目录中查找具有该名称的脚本。
poolie

Answers:



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's

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表示“再次出发”。任何其他退出状态都将打破原本无限的循环。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.