bash—Return 后台函数的状态

bash—Return status from function in background

我有一个bash脚本,大致结构如下:

function download {
    # download a big file
}

function prepare_stuff {
    # prepare some stuff
}

function process_download {
    # process the downloaded file
}

download & prepare_stuff & wait
process_download

它做的第一件事就是下载一个几百兆的文件。在下载过程中,后台准备了一些其他的东西。当这两个都完成后,下载就开始了。

download 可能会以三种不同的方式完成:

  1. 下载失败(例如无法访问服务器)
  2. 文件下载成功
  3. 文件自上次下载后在服务器上没有改变

情况 1 是一个错误条件(在这种情况下函数应该 return 不同于零的东西),而 2 和 3 不是(即 return 值应该是零)。

现在,我希望 process_download 在遇到情况 1 或 3 时跳过实际处理,因此我需要从 download 传回某种状态。由于 download 在子 shell 中运行,变量将不起作用(赋值发生在子 shell 中并且不会传递回父 shell)。

如何将子shell中函数的某种值传递回父shell?

你可以这样做:

download &
download_pid=$!
prepare_stuff &
prepare_pid=$!
result=0
wait $download_pid || result=$?
wait $prepare_pid

然后,result 将包含您之前下载命令的 return 代码,并且两个后台作业都将完成,您可以执行以下操作:

[[ $result = 0 ]] || process_download

关于你的第三个条件的澄清,我可以使答案更完整。

我最终做了类似于弗雷德建议的事情。

首先,我放弃了“文件未在服务器上更改 = 没有错误”的想法,现在使用 return 代码来简单地表示我们是否有要处理的下载——如果是新文件则为 0已下载,如果下载失败或没有任何更改,则为 1。这样处理起来就简单多了。

然后:

function download {
    # download a big file
    # return nonzero if download failed
    # else return nonzero if file has not changed
    # else return 0 (download successful, file has changed)
}

function prepare_stuff {
    # prepare some stuff
}

function process_download {
    # process the downloaded file
}

download &
PID_DOWNLOAD=$!
prepare_stuff &
PID_PREPARE_STUFF=$!
wait $PID_PREPARE_STUFF
wait $PID_DOWNLOAD && process_download || echo "Nothing to process."