繁体   English   中英

使用并行运行的后台进程设置环境变量

[英]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" ,以测试函数是否实际工作。

编辑

我又做了一点调查。 这是问题所在: &将命令/函数放在 subshel​​l 中 这就是变量不可用的原因。 脚本中,如果没有& ,它将是。

man bash

如果命令由控制运算符 & 终止,shell 将在子 shell 的后台执行该命令。 shell 不会等待命令完成,返回状态为 0。这些被称为异步命令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM