LoginSignup
3
4

More than 5 years have passed since last update.

シェルスクリプトで連続処理をより効率的に

Last updated at Posted at 2018-07-20

想定シチュエーション

日付など連続値で順次処理したい。簡単に効率よく速く処理したい。
【例】
- 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サーバでさっと処理できるようになって便利ですね。

3
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4