首页 > 解决方案 > 如何安全地提前退出 bash 脚本?

问题描述

我知道脚本中有几个关于exitvs.return的问题(例如这里)。bash

关于这个话题,但与现有问题不同,我相信,我想知道是否有“最佳实践”来安全地从bash脚本中实现“提前返回”,这样如果他们不退出用户当前的 shell源脚本。

诸如此类的答案似乎基于“ exit”,但如果脚本是来源的,即使用“ .”(点空间)前缀运行,则脚本在当前 shell的上下文中运行,在这种情况下,exit语句具有退出的效果当前外壳。我认为这是一个不受欢迎的结果,因为脚本不知道它是被获取还是在子 shell 中运行 - 如果是前者,用户可能会意外地让他的 shell 消失。如果调用者来源它,是否有提前返回不退出当前 shell 的方法/最佳实践?

例如这个脚本...

#! /usr/bin/bash
# f.sh

func()
{
  return 42
}

func
retVal=$?
if [ "${retVal}" -ne 0 ]; then
  exit "${retVal}"
#  return ${retVal} # Can't do this; I get a "./f.sh: line 13: return: can only `return' from a function or sourced script"
fi

echo "don't wanna reach here"

...如果它是从子外壳运行的,则运行时不会杀死我当前的外壳...

> ./f.sh 
> 

...但是如果它是有源的,它会杀死我当前的外壳:

> . ./f.sh 

想到的一个想法是将代码嵌套在代码中,这样就没有明确的exit声明,但是我的C/C++偏见使认为提前返回在美学上比嵌套代码更可取。还有其他真正“早退”的解决方案吗?

标签: bashshellexitfail-fast-fail-early

解决方案


在不导致父 shell 终止的情况下退出脚本的最常见解决方案是先尝试return。如果它失败了exit

您的代码将如下所示:

#! /usr/bin/bash
# f.sh

func()
{
  return 42
}

func
retVal=$?
if [ "${retVal}" -ne 0 ]; then
  return ${retVal} 2>/dev/null # this will attempt to return
  exit "${retVal}" # this will get executed if the above failed.
fi

echo "don't wanna reach here"

您也可以使用return ${retVal} 2>/dev/null || exit "${retVal}".

希望这可以帮助。


推荐阅读