bash - 如何从异步调用的函数中获取返回值

时间:2017-11-03 15:02:26

标签: bash

我有一个bash脚本,可以像这样异步调用主模块的两个函数:

(func1 && print_msg f1) &
(func2 && print_msg f2) &

[...]

wait $(jobs -p)

如何从func1和func2返回一个值很容易,并且经常被讨论过。我的问题是如何在主模块中访问这些返回值以检查特定值。

1 个答案:

答案 0 :(得分:2)

如果您将退出状态称为功能""返回值",那么wait就可以轻松实现。但是如果你的函数返回比8位整数更复杂的东西,并且在将任务放到后台和返回值检索之间发生了很多,请继续阅读。

简单案例

您已使用的wait内置函数返回它等待的后台进程的退出状态(但仅在显式给出PID时):

  

wait [..]等待ID标识的每个进程,可能是进程ID或作业规范,报告其终止状态。如果未给出ID,则等待所有当前活动的子进程,并且返回状态为零。

例如:

$ f() { sleep 5; return 13; }
$ f &
$ wait $!
$ echo $?
13

更强大的同步

上一个示例非常安全,因为$!始终返回当前shell中最后一个后台进程的PID,f &wait之间没有任何反应。

在两者之间有一些工作的场景中:

f &
pid=$!
# work
wait "$pid"
ret=$?

f的PID(存储在pid中)很可能会被回收 - 如果超过pid_max个进程(默认为{{1}在32768部分期间生成}} work部分中生成的某些进程会收到相同的PID(work)。在发生这种情况之前 - 并且因为pid 缓存其所有孩子的退出状态 - 即使bash的退出状态也会被跟踪,存储和提供在调用f 之前,终止

如果您在上面的f部分中有许多(和/或持久)进程(可能在循环中),您可能希望使用更强大的强健同步机制,或某种形式的IPC,可能是命名管道/ FIFO(可以轻松设置coproc)。

FIFO可以提供结果,但也表示后台作业完成,因此您可以使用它代替wait "$pid"

work