我有一个包含一些数据的数组:
array1=( AAA BBB CCC DDD )
我想用其中的数据填充调用某个 API 的结果数组,array1
同时我想用zenity
.所以我考虑这样做:
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
那里是空的。
我也尝试使用这个语法,但结果相同:
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)
我能做些什么?
答案1
管道的各个部分在子 shell 中运行。 (在 Bash 中,您可以启用该lastpipe
选项以使最后一部分在主 shell 中运行,但这在这里没有帮助。)进程替换也在子 shell 中运行,但它们不会强制主要部分也这样做。
放入 zenity
进程替换并将其保留for
在主 shell 中:
for c in ${array1[@]}; do
...
data_array[$i]=...
...
done > >( zenity \
--progress \
--title="Title" \
--text="Text" \
--percentage=0 \
--auto-close \
--auto-kill )
答案2
另一种可能性:在第一个示例中替换
data_array[$i]=$(curl ... | jq ... | bc)
和
curl ... | jq ... | bc >> /tmp/so-q
并在您的代码后添加:
mapfile -t data_array < /tmp/so-q
rm /tmp/so-q
declare -p data_array
要创建安全的临时文件,您可以使用 mktemp。看man mktemp
。
答案3
也许这不是最优雅的解决方案,但它确实有效。
它依赖于tee
将循环的输出写入文件并zenity
同时通过管道传输到文件中。
使用上面的虚拟代码,它变成:
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
终于有人居住了
~ $ echo ${data_array[@]}
1001 1002 1003 1004