LoginSignup
2
0

More than 1 year has passed since last update.

dateコマンドがGNU dateなのかBSD dateなのか見分ける方法

Last updated at Posted at 2022-10-19

dateコマンドがGNU dateなのかBSD dateなのか見分ける方法です。

結論

date -d 0hour > /dev/null 2>&1 && echo "GNU date" || echo "BSD date"

※ 10/19追記: --version でも同じ結果が得られます。GNU dateには --version がありますが、BSD dateにはありません。

Linux系OS(Ubuntu)での実行結果

date -d 0hour > /dev/null 2>&1 && echo "GNU date" || echo "BSD date"
#=> GNU date

BSD系OS(macOS)での実行結果

date -d 0hour > /dev/null 2>&1 && echo "GNU date" || echo "BSD date"
#=> BSD date

※ シェルがcsh系だと Ambiguous output redirect. となります。

条件判定を逆(True側に BSD date を持ってきたい)場合

date -v+0H > /dev/null 2>&1 && echo "BSD date" || echo "GNU date"

どういうことだってばよ

dateコマンドは、主にLinuxで動く GNU date と、主にmacOSで動く BSD date でオプションが異なります。
特にLinuxとmacOSでは共にBashが動くこともあり、書いたBashスクリプトの99.9%は共通なのに、dateコマンドのせいでションボリというわけです。

※ "date コマンドつらい" なんて話もありますね。
※ top(1) も似たような話がありますね。

そのための判定基準を探したというのが経緯です。

それぞれのdateの違い

最大の違いは、"今から2時間後" といった相対日時算出のオプションがあります。
GNU date は -d (--date) で、BSD date は -v で相対日時を算出します。

また、それぞれに対応するオプションが存在しないので、必ずどちらかで失敗するのを利用して見分けています。

実際にやるとしたら

date コマンドの実行結果 $? を見て分岐することになるでしょう。
下の例では変数に入れてますが、一回しか使わないのであれば $? の直接参照でも良さそうです。

date -d 0hour > /dev/null 2>&1 # inspect
readonly _IS_DATECMD=$([[ "$?" -eq 0 ]] && echo "GNU" || echo "BSD") # judge (likes ternary operator)

echo $_IS_DATECMD
if [ "$_IS_DATECMD" == "GNU" ]; then
  TWO_HOUR_AGO=$(date --date "2 hours ago") # GNU date option
else
  TWO_HOUR_AGO=$(date -v-2H) # BSD date option
fi
echo $TWO_HOUR_AGO

あとがき

さて、私が見分けられるかな…?! (お疲れ

「dateコマンドつらい」ブログは、同僚エンジニアのブログでした。めちゃんこ役立ちました!!あざます ogu++ !!

EoT

2
0
0

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
2
0