【问题标题】:what is the best way to go back to the beginning of a script?回到脚本开头的最佳方法是什么?
【发布时间】:2015-02-11 00:30:59
【问题描述】:

我有一个包含多个输入的脚本,该脚本最终会启动下载,一旦下载完成,我想提示用户在他们想要下载其他内容时重新开始该过程。

while true;do
    read -p "Is this correct? (yes/no/abort) " yno
    case $yno in
        [Yy]*) break;;
        [Nn]*) echo "Lets Start Over" 'restart script code goes here';;
        [Aa]*) exit 0;;
            *) echo "Try again";;

    esac
done

echo
echo "Starting $build download for $opt1 from Jenkins"
echo

while true;do
    read -p "Do you want to download something else? " yesno
    case $yesno in
        [Yy]* ) 'restart script code goes here';;
        [Nn]* ) break;;
        * ) echo "Try Again "
    esac
done

【问题讨论】:

  • 您可以使用exec $0 将当前调用替换为新调用,从顶部开始(并且不使用新进程,这有一些优势)。或者,使用redo=yes; while [ "$redo" = "yes" ]; do ...your current code...; done,如果用户不想再次尝试,您可以在其中修改代码以设置redo=no。在两者之间,循环更为传统。
  • 这与shell脚本无关,您需要在开始实现它们之前学习有关条件语句和循环的基础知识。我建议先创建一个程序流程图。 (用铅笔)

标签: bash recursion


【解决方案1】:

如果你用 shell 函数设计你的 shell 脚本,重复一段代码会变得容易得多:

main() {
    while true; do
        next
        if ! validate_opt 'Do you want to download something else?'; then
            break
        fi
    done
}
validate_opt() {
    local PS3="$1 (Press ctrl-c to exit) "
    local choice
    select choice in yes no; do
        # This can be written more tersely,
        # but for clarity...
        case $choice in
            yes) return 0;;
             no) return 1;;
        esac
    done
}
do_download() {
    echo
    echo "Starting $build download for $opt1 from Jenkins"
    echo
    fetch "$1" # or whatever
}
next() {
    if validate_opt 'Is this correct?'; then
        do_download "$opt"
    else
        echo "Let's start over"
    fi
}
main

【讨论】:

    【解决方案2】:
    function stage1 {
    while true;do
        read -p "Is this correct? (yes/no/abort) " yno
        case $yno in
            [Yy]*) stage2;;
            [Nn]*) continue;;
            [Aa]*) exit 0;;
                *) echo "Try again";;
    
        esac
    done
    }
    
    function stage2 {
    echo
    echo "Starting $build download for $opt1 from Jenkins"
    echo
    
    while true;do
        read -p "Do you want to download something else? " yesno
        case $yesno in
            [Yy]* ) stage1;;
            [Nn]* ) exit 0;;
            * ) echo "Try Again ";;
        esac
    done
    
    }
    stage1
    

    你可以使用函数来做到这一点

    第一个函数是stage 1,第二个stage2 列出所有函数后,在文件底部我们调用 stage1. 当函数 stage1 执行并 $yno= Y* or y* 时,它将跳到 stage2 函数,反之亦然,当我们在 stage2 时

    【讨论】:

    • 这个问题是调用一个函数不只是“跳到”它——它会创建一个堆栈帧,然后,在运行该函数后展开堆栈,返回 back 到函数完成时的旧位置;最终,过多的堆栈帧(如果没有展开)将导致堆栈溢出。
    猜你喜欢
    • 2019-08-24
    • 2010-11-14
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多