Geecul

Geekに踊ってカルチャーと寝る

【備忘】crontabでdateコマンド(正確には”%”)を使おうと思ったらハマった

f:id:youzine:20210718174123p:plain

事象

コマンドを実行してその結果をファイルに出力する記載をcrontabに記載した。

しかし意図した通りにファイルが作成されない。

しかし手動でコマンドを実行する正常に動作する。


        #うまくいかないcrontab記載の例
        [example@ec2 ~]# crontab -l
        15 7 * * * echo 'Hello World!' > /work/Hello_`date +%Y%m%d%-%H%M%S`.log
        [example@ec2 ~]#
    
      #出力先ディレクトリを確認しても何もない
        [example@ec2 ~]# ls -l /work
        total 0
        [example@ec2 ~]#
        
        #ログを確認するとコマンドが記載通りに実行されていないことが分かる
        [example@ec2 ~]# cat /var/log/cron | tail -5
        Jul 18 07:15:01 ip-############# crond[3000]: (root) RELOAD (/var/spool/cron/root)
    Jul 18 07:15:01 ip-############# CROND[8018]: (root) CMD (echo 'Hello World!' > /work/Hello_`date +)
    Jul 18 07:20:01 ip-############# CROND[8296]: (root) CMD (/usr/lib64/sa/sa1 1 1)
    Jul 18 07:30:01 ip-############# CROND[8797]: (root) CMD (/usr/lib64/sa/sa1 1 1)
    Jul 18 07:32:10 ip-############# crontab[8983]: (root) LIST (root)
        [example@ec2 ~]#
        
        

 

結論

出力するファイルの名前に日時を含むようdateコマンドを使っていたのだが、その際に%がエスケープされていなかったのが原因だった。

crontabに%を記載する際にはエスケープする必要がある。つまりdateコマンドでフォーマット指定する際の%にもエスケープしないと意図した通りにならない。

そのことはcrontabファイルの説明にも記載されている(「man 5 crontab」を打鍵して確認することができる)。

以下に正しくcrontabで%を使用する際の例を記載する。


        #うまくいく場合のcrontab記載の例(エスケープしている)
        [example@ec2 ~]# crontab -l
        50 7 * * * echo 'Hello World!' > /work/Hello_`date +\%Y\%m\%d-\%H\%M\%S`.log
        [example@ec2 ~]#
    
      #出力先ディレクトリを確認するとファイルが作成されている
        [example@ec2 ~]# ls -l /work
        total 4
    -rw-r--r-- 1 root root 13 Jul 18 07:50 Hello_20210718-075001.log
        [example@ec2 ~]#
        
        #ログを確認するとコマンドが記載通りに実行されていることが分かる
        [example@ec2 ~]# cat /var/log/cron | tail -5
       Jul 18 07:49:54 ip-############# crontab[9868]: (root) END EDIT (root)
    Jul 18 07:50:01 ip-############# crond[3000]: (root) RELOAD (/var/spool/cron/root)
    Jul 18 07:50:01 ip-############# CROND[9964]: (root) CMD (echo 'Hello World!' > /work/Hello_`date +%Y%m%d-%H%M%S`.log)
    Jul 18 07:50:01 ip-############# CROND[9965]: (root) CMD (/usr/lib64/sa/sa1 1 1)
    Jul 18 07:51:22 ip-############# crontab[10049]: (root) LIST (root)
        [example@ec2 ~]#
        

メモ

  • 上記コードブロックの例はこの記事用にawsのEC2(Amazon Linux)上で実行した。
  • この事象とcrontabの仕様はAIX上で気づいた。AIXでも同様に%はエスケープする必要がある。
  • この記事作成で知ったが、AIXとLinuxでは結構cron周りにも違いがあることが分かった(/etc/crontabの有無、cronのログ出力先等)。/li>
  • 色々違いとか洗い出して比較してみたら面白そう。

リンク

ja.wikipedia.org

www.ibm.com

www.ibm.com

 

3209107によるPixabayからの画像