[英]Setting environment variables with background processes running in parallel
我有一个需要 1 分钟才能获取的文件。 因此,在我需要获取的文件中,我创建了函数,然后使用 & 并行运行它们。 从子进程导出的变量在当前环境中不可用。 是否有解决此问题的解决方案或技巧? 谢谢。 样本:
#!/bin/bash
function getCNAME() {
curl ...... grep
export CNAME
}
function getBNAME() {
curl ...... grep
export BNAME
}
getCNAME &
getBNAME &
然后我有一个主文件,它在上面的代码中调用 source 命令并尝试使用变量 BNAME 和 CNAME。 却无能为力。 如果我删除 & 它确实可以访问这些变量,但需要很长时间来获取文件。
您不能在子 shell 中使用export
并期望父 shell 能够访问结果变量。 考虑使用进程替换:
#!/bin/bash
# note that if you're sourcing this, as you should be, the shebang will be ignored.
# ...hopefully it's just there for your editor's syntax highlighting.
rc=0
orig_pipefail_setting=$(shopt -p pipefail)
shopt -s pipefail # make sure if either curl _or_ grep fails the entire pipeline does too
# start both processes in the background, with their stdout on two different FDs
exec 4< <(curl ... | grep ... && printf '\0')
exec 5< <(curl ... | grep ... && printf '\0')
# read from those FDs into variables in the current shell
IFS= read -r -d '' BNAME <&4 || { (( rc |= $? )); echo "Error reading BNAME" >&2; }
IFS= read -r -d '' CNAME <&5 || { (( rc |= $? )); echo "Error reading CNAME" >&2; }
exec 4<&- 5<&- # close those file descriptors now that we're done with them
export BNAME CNAME # note that you probably don't actually need to export these
eval "$orig_pipefail_setting" # turn pipefail back off, if it wasn't on when we started
return "$rc" # ...return with an exit status reflecting whether we had any errors
这样,文件描述符 4 和 5 将分别附加到运行curl
并将其输出提供给grep
的 shell 管道; 在我们尝试从中读取之前,它们都在后台启动,因此它们同时运行。
你确定最后两行不应该是:
getCNAME
getBNAME
编辑 - OP 已修复此问题,它用于读取:
CNAME
BNAME
如果您正在获取脚本 ( . /my/script
),则它不是子进程,并且其变量将在当前 shell 中可用。 你甚至不需要导出。
如果正常执行脚本,则是子进程,不能在父shell中设置变量。
我所知道的将数据传输到父 shell 的唯一方法是通过文件。
变量应该是可用的。 检查脚本中的错误:
确保您没有对函数中的变量使用local
。
在源脚本的底部执行echo "$CNAME"
,以测试函数是否实际工作。
编辑
我又做了一点调查。 这是问题所在: &
将命令/函数放在 subshell 中。 这就是变量不可用的原因。 在源脚本中,如果没有&
,它将是。
从man bash
:
如果命令由控制运算符 & 终止,shell 将在子 shell 的后台执行该命令。 shell 不会等待命令完成,返回状态为 0。这些被称为异步命令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.