bash-从后台函数返回状态

时间:2017-01-27 19:23:49

标签: bash subshell

我有一个大致具有以下结构的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. 自上次下载以来,服务器上的文件未发生变化
  4. 情况1是一个错误条件(在这种情况下函数应该返回不同于零的东西),而2和3不是(即返回值应为零)。

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

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

2 个答案:

答案 0 :(得分:2)

你可以这样做:

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

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

[[ $result = 0 ]] || process_download

通过对第三个条件的澄清,我可以使答案更加完整。

答案 1 :(得分:0)

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

首先,我放弃了“文件未在服务器上更改=没有错误”的想法,现在使用返回代码简单地表示我们是否下载到处理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."