想定シチュエーション
日付など連続値で順次処理したい。簡単に効率よく速く処理したい。
【例】
- 20170101~20171231までのログファイルがあって、それぞれに処理を行いたい。
- sh execute.sh -d 20170101
で 1日分の処理が行える。
なにも考えないと
01.sh
sh execute.sh -d 20170101
sh execute.sh -d 20170102
(中略)
sh execute.sh -d 20171231
Excelで365行のコマンドを作って処理。だれもがやったことがあるのでは。
脱Excel
02.sh
STARTYMD=20170101
ENDYMD=20171231
TD=${STARTYMD}
ENDYMD=`date -d "${ENDYMD} 1 days" '+%Y%m%d'` # 便宜上+1日してるだけ。
while [ ${TD} -ne ${ENDYMD} ]; do
sh execute.sh -d ${TD}
TD=`date -d "${TD} 1 days" '+%Y%m%d'`
done
日付を追うのはdateコマンドに任せる。日付ではなく連番であれば単にforを使う。
02-2.sh
STARTNUM=1
ENDNUM=10
for NUM in $(seq ${STARTNUM} ${ENDNUM}); do
sh execute.sh -n ${NUM}
done
CPUを効率的に
上記では1コアしか使わず、今どきのPC/Serverでは力を持て余すので、コア数分だけ分ける。
03child1.sh
STARTYMD=20170101
ENDYMD=20170331
(略)
03child2.sh
STARTYMD=20170401
ENDYMD=20170630
(略)
03child3.sh
STARTYMD=20170701
ENDYMD=20170930
(略)
03child4.sh
STARTYMD=20171001
ENDYMD=20171231
(略)
command
$ sh 03child1.sh &
$ sh 03child2.sh &
$ sh 03child3.sh &
$ sh 03child4.sh &
これで4コア並行で使える。
並列処理も自動に
04.sh
STARTYMD=20170101
ENDYMD=20171231
THREADS=$(nproc --all) # コア数取得
TD=${STARTYMD}
ENDYMD=`date -d "${ENDYMD} 1 days" '+%Y%m%d'` # 便宜上+1日してるだけ。
while [ ${TD} -ne ${ENDYMD} ]; do
sh execute.sh -d ${TD} & # バックグラウンドにしてしまう。
while [[ $(jobs | wc -l) -ge ${THREADS} ]]; do sleep 1; done # コア数まで処理中になったら待つ
TD=`date -d "${TD} 1 days" '+%Y%m%d'`
done
wait # これを付けるとすべての処理の完了を待つ
今どきは32コアマシンとかポチポチで起動できちゃうので、1サーバでさっと処理できるようになって便利ですね。