在同步shell中运行异步shell命令,即等待结果
我希望异步运行命令,但只有在所有命令都完成后才能返回提示 比如说 我想做这样的事情 睡眠1和睡眠7和睡眠3和睡眠4 并在7秒后释放外壳 例如,我将使用多个卷发同时下载,并在下载所有内容时得到提示 将它们包装在$()中就可以了 比如说在同步shell中运行异步shell命令,即等待结果,shell,asynchronous,Shell,Asynchronous,我希望异步运行命令,但只有在所有命令都完成后才能返回提示 比如说 我想做这样的事情 睡眠1和睡眠7和睡眠3和睡眠4 并在7秒后释放外壳 例如,我将使用多个卷发同时下载,并在下载所有内容时得到提示 将它们包装在$()中就可以了 比如说 time$(sleep 1和sleep 7和sleep 3和sleep 4)会在7秒后返回提示传统方法是收集PID并依次等待;这意味着您知道命令的退出状态以及是否有任何命令失败 #!/bin/bash # ^^- important: the below uses
time$(sleep 1和sleep 7和sleep 3和sleep 4)会在7秒后返回提示传统方法是收集PID并依次等待;这意味着您知道命令的退出状态以及是否有任何命令失败
#!/bin/bash
# ^^- important: the below uses bash/ksh extensions not available in /bin/sh
pids=( )
sleep 1 & pids+=( $! )
sleep 6 & pids+=( $! )
sleep 3 & pids+=( $! )
sleep 4 & pids+=( $! )
num_failures=0
for pid in "${pids[@]}"; do
wait "$pid" || (( ++num_failures ))
done
if (( num_failures > 0 )); then
echo "Warning: $num_failures background processes (out of ${#pids[@]} total) failed" >&2
fi
如果您需要与
/bin/sh
兼容,则会有一些变化:
#!/bin/sh
pids=''
sleep 1 & pids="$pids $!"
sleep 6 & pids="$pids $!"
sleep 3 & pids="$pids $!"
sleep 4 & pids="$pids $!"
num_failures=0
for pid in $pids; do
wait "$pid" || num_failures=$(( num_failures + 1 ))
done
if [ "$num_failures" -gt 0 ]; then
echo "Warning: $num_failures background processes failed" >&2
fi
…或者,如果足以等待所有后台作业,而没有详细的失败状态,则:
仅仅因为它有效并不意味着它是个好主意。您正在从这些
sleep
命令中读取stdout,并将组合的stdout作为命令运行;当然这不是你想要的副作用。(试着把你的第一个sleep 1&
改成{echo touch/tmp/i-can-run-ar任意-code;sleep 1;}&
,然后查看/tmp
——您会发现,如果有任何程序可以通过这种方式远程控制后台运行的所有东西,那么实际上存在潜在的安全影响)。值得一提的是,除非您有不想等待的后台作业,您只需调用wait
,而无需存储后台作业的所有进程ID。
sleep 1 & sleep 6 & sleep 3 & sleep 4 &
wait