Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在同步shell中运行异步shell命令,即等待结果_Shell_Asynchronous - Fatal编程技术网

在同步shell中运行异步shell命令,即等待结果

在同步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

我希望异步运行命令,但只有在所有命令都完成后才能返回提示

比如说

我想做这样的事情 睡眠1和睡眠7和睡眠3和睡眠4

并在7秒后释放外壳

例如,我将使用多个卷发同时下载,并在下载所有内容时得到提示

将它们包装在$()中就可以了

比如说


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