일부 데이터가 포함된 배열이 있습니다.
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
파이프라인의 다양한 부분이 서브셸에서 실행됩니다. (Bash에서는 lastpipe
마지막 부분이 기본 셸에서 실행되도록 하는 옵션을 활성화할 수 있지만 여기서는 도움이 되지 않습니다.) 프로세스 대체도 하위 셸에서 실행되지만 기본 부분이 동일한 작업을 수행하도록 강제하지는 않습니다.
zenity
프로세스 교체를 넣고 for
메인 셸에 보관하세요.
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