首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么bash数组仍然是空的,如果我将用于填充的for循环的结果输送到zenity -过程中呢?

为什么bash数组仍然是空的,如果我将用于填充的for循环的结果输送到zenity -过程中呢?
EN

Unix & Linux用户
提问于 2021-11-14 19:47:08
回答 3查看 231关注 0票数 0

我有一个包含一些数据的数组:

array1=( AAA BBB CCC DDD )

我想用array1中的数据填充调用某个API的结果数组,同时我想展示使用zenity的进展情况。所以我想做这个:

代码语言:javascript
复制
i=0
prog=0

for c in ${array1[@]}; do
  echo $prog  #updates the text
  echo "# $c" #updates the percentage

  data_array[$i]=$(curl -s "https://hub.dummyapis.com/products?noofRecords=4&idStarts=1001&useless=$c" | jq .[$i].id | bc)

  (( prog=prog+30 ))
  (( i++ ))
done | zenity \
    --progress \
    --title="Title" \
    --text="Text" \
    --percentage=0 \
    --auto-close \
    --auto-kill

问题是data_array仍然是空的。

另一方面,如果我省略了zenity命令的管道,它就会被填充。如果我正确理解的话,这是因为管道产生了一个新的子进程,因此data_array在那里是空的。

我也试过使用这个新税,但结果是一样的:

代码语言:javascript
复制
zenity \
    --progress \
    --title="Title" \
    --text="Text" \
    --percentage=0 \
    --auto-close \
    --auto-kill < <(
for c in ${array1[@]}; do
  echo $prog
  echo "# $c"

  data_array[$i]=$(curl -s "https://hub.dummyapis.com/products?noofRecords=4&idStarts=1001&useless=$c" | jq .[$i].id | bc)

  (( prog=prog+30 ))
  (( i++ ))
done)

我能做什么?

EN

回答 3

Unix & Linux用户

回答已采纳

发布于 2021-11-15 20:03:09

管道的各个部分在子壳中运行。(在Bash中,您可以启用lastpipe选项在主shell中运行最后一部分,但这在这里没有帮助。)进程替换也在子subshells中运行,但它们也不强制主要部分这样做。

zenity放在进程替换中,并将for保存在主外壳中:

代码语言:javascript
复制
for c in ${array1[@]}; do
  ...
  data_array[$i]=...
  ...
done > >( zenity \
    --progress \
    --title="Title" \
    --text="Text" \
    --percentage=0 \
    --auto-close \
    --auto-kill )
票数 1
EN

Unix & Linux用户

发布于 2021-11-15 17:40:12

另一种可能性:在第一个示例中替换

代码语言:javascript
复制
data_array[$i]=$(curl ... | jq ... | bc)

使用

代码语言:javascript
复制
curl ... | jq ... | bc >> /tmp/so-q

并在代码后面添加:

代码语言:javascript
复制
mapfile -t data_array < /tmp/so-q
rm /tmp/so-q
declare -p data_array

要创建安全的临时文件,可以使用mktemp。见man mktemp

票数 1
EN

Unix & Linux用户

发布于 2021-11-15 15:56:02

也许这不是最优雅的解决方案,但有效。

它依赖于tee将循环的输出写入文件并同时通过管道传输到zenity

使用上面的虚拟代码,它变成:

代码语言:javascript
复制
array1=( AAA BBB CCC DDD )

curl_cmd() {
  curl -s "https://hub.dummyapis.com/products?noofRecords=4&idStarts=1001&useless=$1" | jq .[$2].id | bc
}

i=0
prog=0

for c in ${array1[@]}; do
  #updates the text
  echo $prog
  #updates the percentage
  echo "# $c"

  #echo the data I'm interested in, 
  #with a @ for later reference
  echo "@ $(curl_cmd $c $i)" 

  (( prog=prog+30 ))
  (( i++ ))
done | tee >(zenity \
    --progress \
    --title="Title" \
    --text="Text" \
    --percentage=0 \
    --auto-close \
    --auto-kill) > /tmp/so-q

data_array=( $(grep @ /tmp/so-q | cut -c 2-) )

现在,data_array终于被填充了

代码语言:javascript
复制
~ $ echo ${data_array[@]}
1001 1002 1003 1004
票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/677519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档