仕事でSolarisサーバーからシステム日付の前月と前々月の年月を
YYYYMM形式で取得する処理のシェルスクリプトを書くことになりました。
この時に、一筋縄ではいかないことがありました。
その時にどうやって対処したかを記載します。
一番簡単な方法
普通、日付の1か月前の計算はこのようにして行います。
# 1カ月前
$ date -d ‘1 month ago’
このように-dオプション又は-dateオプションを使います。
ところが、同じUnix系なのにSolarisでは使えません。
(参照:http://www.fujitsu.com/jp/products/computing/servers/unix/sparc/technical/command-reference/sys2/07.html)
Solarisのdateコマンドで過去や未来の日付を出すには
sh-utils若しくはshutilsというパッケージをインストールすればいいらしいです。
(参照:https://blogs.yahoo.co.jp/bobuton/26034312.html)
そこで、これを本番環境でインストールしてもいいかお客様に尋ねたところ
「他の重要な処理に影響が出たら困るので、避けてほしい」
との回答が……。
ということで、-dオプションを使わずに日付計算をすることになりました。
最初は、タイムゾーンを設定することで取得できると調べたときにわかり、考えたのが
LASTMONTH=`JST+15 date “+%Y%m”`
(1日前の年月日時刻を取得し、YYYYMM形式で表示)
(参照:http://shellscript.sunone.me/date.html#gnu-date-が使用できない場合-1)
でした。
この処理が「毎月1日に行われる」ことを利用した策ですが
実行日を変更するとき、わざわざこの“+15”を変えないといけません。
これではいつの日にか、ユーザー様にご迷惑をお掛けすることになりますね。
しかも、これは最大でも1週間程度までしか遡れなかったので
中旬以降に実施することに変更になってしまえば、たちまち使えなくなってしまいます。
別の手段を探すことになりました。
そして、日付を整数として計算するという方法を見つけました。
(参照:http://shellscript.sunone.me/date.html#先月の月を取得する)
まずは、システム日付を年月だけの形式(YYYYMM)で取得します。
SYSDATE=`date “+%Y%m”`
1カ月前なら、この変数SYSDATEを整数扱いにして1を引けばいいので
LASTMONTH=`expr ${SYSDATE} -1`
しかし、これではある罠にはまってしまうことに気付きました。
例えば、この処理が2018年1月に行われたとき、どうなるでしょうか。
LASTMONTH=201801-1=201800
と、2018年0月となってしまいます。
これでは具合が悪いので
1月にこの処理が行われた時とそうじゃない時とで条件分岐を与え
別の処理を施す必要が出てきました。
最初に思いついたのは
この変数LASTMONTHを月だけに分け
LASTMONTH_M=${LASTMONTH:4:2}(これで変数から部分的に文字列を取得する)
このLASTMONTH_Mが”00”になるときは
LASTMONTH=LASTMONTH-88
をするということでした。
実際、2018年1月にこの処理を実行したとすると
LASTMONTH=201801-1=201800
LASTMONTH_M=00
LASTMONTH=201800-88=201712
となります。
ただ、これでいいかどうか、相談してみたところ
月計算で88を使うなんて直感的ではない、分かりにくいと指摘を受けました。
それとともに、年と月で分けて計算したほうがいいのではないか?とアドバイスをもらいました。
その後、次のように変更しました。
LASTMONTH=`expr ${SYSDATE} -1`
LASTMONTH_Y=`${LASTMONTH:0:4}`
LASTMONTH_M=`${LASTMONTH:4:2}`
if [${LASTMONTH_M} -eq “00”]; then
LASTMONTH_Y=`expr ${LASTMONTH_Y} -1`
LASTMONTH=”${LASTMONTH_Y}12”
fi
取得した前月を年と月に分け
前月が“00”になったとき
年だけ1引いて
その年の後ろに“12”を付け足すという考えです。
実際に2018年1月に実行されたとして計算してみると
LASTMONTH=`expr ${SYSDATE} -1` =201801-1=201800
LASTMONTH_Y=`${LASTMONTH:0:4}` =2018
LASTMONTH_M=`${LASTMONTH:4:2}` =00
if [${LASTMONTH_M} -eq “00”]; then
LASTMONTH_Y=`expr ${LASTMONTH_Y} -1` =2018-1=2017
LASTMONTH=”${LASTMONTH_Y}12” =201712
fi
このように前月を取得することができます。