如何在Bash中退出if语句而不退出程序?

4

为避免更多的否决,我重写了这个问题,因为现在已经太晚删除它:

我正在编写一个脚本,询问用户是否确认并在 sourcing 一些其他脚本之前。为了简化代码,假设有两个脚本可能被 sourced,但我希望用户要么不 source 任何一个,要么只选择一个脚本 - 而不是两个都选。我尝试使用类似于 if true source-script else exit 的语句,但这样做不起作用,因为我退出了 if 语句,同时也退出了整个脚本,并且没有机会进行必要的清理工作。最初,我的脚本看起来像这样:

echo "This script might do something terrible to your computer."
read -p "Do you wish to continue? (y/[n]) " -n 1;
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]
then
    source "terrible_script.sh"
    # want some way to ensure that we don't prompt the user about the next script
    # don't want to just exit if the response is 'n' because we have to do cleanup
fi

echo "This script might do something really good to your computer."
read -p "Do you wish to continue? (y/[n]) " -n 1;
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]
then
    source "good_script.sh"
fi

# do cleanup here
# regardless of whether or not any scripts were sourced

@charles-duffy提供了答案——只需将提示信息包装在一个函数中即可。类似这样:

function badscript() {
    echo "This script might do something terrible to your computer."
    read -p "Do you wish to continue? (y/[n]) " -n 1;
    echo
    if ! [[ $REPLY =~ ^[Yy]$ ]]
    then
        source "terrible_script.sh"
        return 0
    fi
}

function goodscript() {
    echo "This script might do something really good to your computer."
    read -p "Do you wish to continue? (y/[n]) " -n 1;
    echo
    if ! [[ $REPLY =~ ^[Yy]$ ]]
    then
        source "good_script.sh"
    fi
}

if ! badscript
then
    goodscript
fi

# cleanup code here

2
“exit” 被定义为退出 shell。这就是它的定义。你为什么会期望它能够做任何不同的事情呢? - Charles Duffy
1
现在,有一个“break”命令可以从循环中提前退出,但是如果没有将其包装在循环内部,就无法使用它来跳出“if”。 - Charles Duffy
在zsh中,return可以在if语句内部使用。 - smac89
3个回答

10

首先:不要这样做。请以其他方式构建程序。如果您向我们描述了为什么您认为需要这种行为,那么我们可能会告诉您如何通过其他方式实现它。


进入问题:如果您将块包装在循环中,则可以使用break提前退出:

for _ in once; do
  if true; then
    echo "in the loop"
    break
    echo "not reached"
  fi
done
echo "this is reached"

另外,你可以使用一个函数,并使用return提前退出:

myfunc() {
  if true; then
    echo "in the loop"
    return
  fi
  echo "unreached"
}
myfunc
echo "this is reached"

另外,您可以将循环包装在子shell中(但这将阻止它执行其他操作,比如变量分配会影响子shell外的代码):

(if true; then
   echo "in the block"
   exit
   echo "unreached"
 fi)
echo "this is reached."

1

为什么要打印exit。如果你想跳出循环,只需删除exit及其下面的所有代码(如果存在),因为无论如何它都不会运行。

如果您计划使用循环并希望退出循环,请使用break退出循环。


0

只需删除exit。它将输出开始语句,然后打印hello。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接