我有以下脚本:
echo "$wk" | while read -r a b;
do
counter=$(($counter+1))
nohup sh -c 'impala-shell -d nielsen -f query.sql --var=dt=$a --var=incre=$b;
echo $a,$?>>$week_status_file;
if [ $? -ne 0 ]; then
echo $a,$b>>$err_week_file
fi'
if [ $(($counter%5)) == 0 -a $counter -ge 5 ];
then
echo "Check"
wait
fi
done
impala-shell...
这个想法是用两个变量a
和b
(来自变量)启动包装的命令wk
。这应该与 5 个进程并行完成。接下来的 5 个作业应等待前 5 个进程完成。我当前的代码打印出来Check
,但它根本不等待。但是,如果我更改wait
为sleep 10s
,它就会休眠。
我如何wait
在这里工作?
答案1
您必须向 提供进程标识符 (PID) wait
。另外,从您的描述来看,您的命令听起来并不像是阻塞的,这最终会使收集您想要等待的 PID 变得更加困难。例如,如果进程正在分叉并允许您在不知道新分叉进程的 PID 的情况下继续编写脚本。
但如果您的nohup sh -c ...
线路被阻塞,您希望使用 发送到后台&
,保存后台进程的 PID,最后等待您保存的所有 PID(例如在 中$WAIT_FOR_PIDS
)。变量$!
为您提供发送到后台执行的最后一个进程的 PID。
WAIT_FOR_PIDS="";
echo "$wk" | while read -r a b;
do
counter=$(($counter+1))
nohup sh -c 'impala-shell -d nielsen -f query.sql --var=dt=$a --var=incre=$b;
echo $a,$?>>$week_status_file;
if [ $? -ne 0 ]; then
echo $a,$b>>$err_week_file
fi' & WAIT_FOR_PIDS="$WAIT_FOR_PIDS $!"
if [ $(($counter%5)) == 0 -a $counter -ge 5 ];
then
echo "Check"
wait $WAIT_FOR_PIDS
WAIT_FOR_PIDS=""
fi
done
此外,您还应该在并行回显时考虑竞争条件$week_status_file
。请man flock
参阅 轻松 shell 可访问的文件锁定。