저는 여러 계정에서 Offlineimap을 실행하고 있으며 각 실행에 대한 종료 코드를 확인하고 그에 따라 작업을 수행하고 싶습니다.
나는 코드 중복을 많이 실행하는 6개의 별도 이메일 계정을 가지고 있습니다. 원래 명령 구조는 다음과 같습니다.
$ $(which offlineimap) -c offlineimaprc -o -a yahoo & declare yahoo_pid=$!
wait $yahoo_pid
yahoo_st=$?
if [[ $yahoo_st -ne 0 ]];then <do some stuff>
$ $(which offlineimap) -c offlineimaprc -o -a gmail & declare gmail_pid=$!
wait $gmail_pid
gmail_st=$?
if [[ $gmail_st -ne 0 ]];then <do some stuff>
for in
이제 중복 항목을 제거하고 루프 및 wait
명령 에서 실행하고 싶습니다 . ${account-name}_pid(예: yahoo_pid) 대체는 잘 작동하지만 wait
해당 명령이 계속 실행되지 않습니다.
$ for app in yahoo gmail
do
$(which offlineimap) -c offlineimaprc -o -a ${app} & declare ${app/%/_pid}=$!
wait ${app}_pid
done
[1] 73443
-bash: wait: `$yahoo_pid': not a pid or valid job spec
[2] 73444
-bash: wait: `$gmail_pid': not a pid or valid job spec
답변1
app=(yahoo gmail)
# ...
declare ${app/%/_pid}=$!
위의 것은 이상해 보입니다. app
배열이지만 참조만 하면 와 $app
마찬가지로 배열의 첫 번째 요소를 가져옵니다 ${arr[0]}
. 따라서 항상 에 할당됩니다 yahoo_pid
.
$(eval echo \$${app}_st)=$?
이것은 단순히 작동하지 않습니다. 등호 왼쪽의 확장은 이를 잘못된 할당으로 만들고 쉘은 이를 명령으로 처리합니다. $yahoo_st
설정되지 않은 경우 , $?
예를 들어 0
이라는 명령을 실행하려고 시도합니다 =0
.
어쨌든, 당신의 경우에는요.
Bash에는 연관 배열, 즉 문자열로 인덱스된 배열이 있는데, 이는 거의 정확히 필요한 것입니다. 선언해야 하며 declare -A
, 위와 같이 일반 배열을 할당할 수 있습니다.
imap=$(which offlineimap)
apps=(yahoo gmail)
declare -A pids=()
declare -A st=()
for app in "${apps[@]}"; do
"$imap" -c offlineimaprc -o -a "$app" &
pids[$app]=$!
wait "${pids[$app]}"
st[$app]=$?
done
# and to check on them later:
for app in "${apps[@]}"; do
printf "app '%s' ran pid %s returning status %s\n" "$app" "${pids[$app]}" "${st[$app]}"
done
아니면:
for app in "${apps[@]}"; do
"$imap" -c offlineimaprc -o -a "$app" &
pids[$app]=$!
done
for app in "${apps[@]}"; do
wait "${pids[$app]}"
st[$app]=$?
done
# ...
또는 namerefs를 사용하여 다른 변수 내에 명명된 변수를 참조할 수 있습니다. pid_yahoo
그러면 다음이 설정됩니다 st_yahoo
.
app=yahoo
declare -n pid="pid_$app"
declare -n st="st_$app"
something... & pid=$!
wait "$pid"
st=$?
그러나 실제로는 연관 배열을 사용하십시오.
예를 들어 참조하십시오.
답변2
질문에서 답변으로 이동
마침내 이것에 투자하기 위해서는 많은 검색과 예시가 필요했지만, 마침내 나에게 효과가 있었던 것은 다음과 같습니다.
app=(yahoo gmail)
$(which offlineimap) -c offlineimaprc -o -a ${app} & declare ${app/%/_pid}=$!
wait $(eval echo \$${app}_pid) <<== THIS IS THE MAGIC SYNTAX
$(eval echo \$${app}_st)=$? && if [[ $(eval echo \$${app}_st) -ne 0 ]];then error_msg ${app}; fi