我有一个包含一些数据的数组:
array1=( AAA BBB CCC DDD )
我想用array1中的数据填充调用某个API的结果数组,同时我想展示使用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)我能做什么?
发布于 2021-11-15 20:03:09
管道的各个部分在子壳中运行。(在Bash中,您可以启用lastpipe选项在主shell中运行最后一部分,但这在这里没有帮助。)进程替换也在子subshells中运行,但它们也不强制主要部分这样做。
将zenity放在进程替换中,并将for保存在主外壳中:
for c in ${array1[@]}; do
...
data_array[$i]=...
...
done > >( zenity \
--progress \
--title="Title" \
--text="Text" \
--percentage=0 \
--auto-close \
--auto-kill )发布于 2021-11-15 17:40:12
另一种可能性:在第一个示例中替换
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。
发布于 2021-11-15 15:56:02
也许这不是最优雅的解决方案,但有效。
它依赖于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 1004https://unix.stackexchange.com/questions/677519
复制相似问题