我在一堆帐户上运行offlineimap,并希望检查每次运行的退出代码,并相应地执行一些操作。
我有6个单独的电子邮件帐户,我与许多代码重复运行。最初的命令结构是:
$ $(which offlineimap) -c offlineimaprc -o -a yahoo & declare yahoo_pid=$!
wait $yahoo_pid
yahoo_st=$?
if [[ $yahoo_st -ne 0 ]];then
$ $(which offlineimap) -c offlineimaprc -o -a gmail & declare gmail_pid=$!
wait $gmail_pid
gmail_st=$?
if [[ $gmail_st -ne 0 ]];then
现在,我想删除复制,并从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
发布于 2022-05-24 14:14:50
app=(yahoo gmail)
# ...
declare ${app/%/_pid}=$!
上面这个看起来很奇怪。虽然app
是一个数组,但仅引用$app
将从数组中获得第一个元素,与${arr[0]}
相同。因此,这将始终分配给yahoo_pid
。
$(eval echo \${app}_st)=$?
这根本行不通。在等于符号的左侧展开使其成为无效赋值,shell将将其作为命令处理。如果没有设置$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
# ...
或者,您可以使用名称引用在另一个变量中命名的变量。这将设置pid_yahoo
和st_yahoo
:
app=yahoo
declare -n pid="pid_$app"
declare -n st="st_$app"
something... & pid=$!
wait "$pid"
st=$?
但实际上只是使用关联数组。
另见下文。
https://unix.stackexchange.com/questions/703675
复制