如何返回到源Bash脚本?

79

我在一个Bash脚本中使用"source",如下所示:

#!/bin/bash
source someneatscriptthatendsprematurely.sh

我想从 someneatscriptthatendsprematurely.sh 脚本中退出,但不想退出主脚本。

感谢任何帮助!

3个回答

120

你需要使用return语句:

return [n]

这个语句会使函数以指定的返回值n退出。如果省略n,则返回在函数体中执行的最后一条命令的返回状态。如果在函数之外使用,但是在通过.(source)命令执行脚本过程中使用,它将导致shell停止执行该脚本并返回n或者脚本中最后一个命令的退出状态作为脚本的退出状态。如果在函数之外且不在通过.执行脚本的过程中使用,则返回状态为假。在函数或脚本执行后,执行与RETURN陷阱相关联的任何命令,然后才能恢复执行。

可以通过以下两个示例脚本来看到其效果:

script1.sh:
    . script2.sh
    echo hello again

script2.sh:
    echo hello
    return
    echo goodbye

当你运行 script1.sh 时,你会看到:

hello
hello again

5
请注意,如果可能的话,默认情况下应明确地返回0。否则可能会导致父脚本中出现意外行为。例如,[ -z "non-existant-file" ] && return 实际上将返回1。 - Brett Ryan
5
@BrettRyan的例子有问题,因为[ -z "non-existant-file" ] && return 0会返回1。所以告诉人们明确地return 0,然后展示一个不起作用的例子是令人困惑的。 - Segfault
Brett,在我发布的示例中实际上并不重要,因为调用脚本实际上没有以任何方式检查返回值(例如,通过 if$?set -e)。无论如何,我非常确定我包含的引用在这种情况下使行为清晰明了。 - paxdiablo

0

我刚刚也遇到了同样的问题

我意识到添加一个检查函数并返回它不会同时返回调用者的函数,例如。

在bash_functions中

function install_packer_linux() {
  check_wget && check_unzip
  wget https://releases.hashicorp.com/packer/1.1.2/packer_1.1.2_linux_amd64.zip
  unzip packer_1.1.2_linux_amd64.zip
  mv packer ~/.local/bin
  rm -f packer_1.1.2_linux_amd64.zip
}


function check_unzip() {
  if ! [ -x "$(command -v unzip)" ]; then
    echo "Error: unzip is not installed"
    return 1
  else
    return 0
  fi
}

function check_wget() {
  if ! [ -x "$(command -v wget)" ]; then
    echo "Error!: wget is not installed"
    return 1
  else
    return 0
  fi
}


$ source ~/.bash_functions

这里发生的情况是,由于检查器是唯一返回的地方,因此install_packer_linux将继续执行

因此,您可以在这里做两件事。要么保持当前格式(函数调用另一个函数)不变,并使用真值进行评估,然后如果值不是真值,则返回;或者重写主安装程序_packer_linux函数上的检查器

真值:

function install_packer_linux() {
  check_wget && check_unzip || return
  wget https://releases.hashicorp.com/packer/1.1.2/packer_1.1.2_linux_amd64.zip
  unzip packer_1.1.2_linux_amd64.zip
  mv packer ~/.local/bin
  rm -f packer_1.1.2_linux_amd64.zip
}

请注意,我们在检查完成后添加了 || return 并使用 && 连接了这些检查条件。 因此,如果不是两个检查条件都为真,我们就会返回函数。

0

你能改变环境变量是否很重要?否则,你只能通过执行脚本而非源代码来执行它:

someneatscriptthatendsprematurely.sh

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