目次
Rails などで、 setup を自動にしている人は多いと思います。 Rails だと whenever という gem を使って crontab をプログラムから設定してしまうことができるのですが、 メールサーバなど Rails をインストールしていない、 インストールするのも煩わしい環境だとそうはいきません。 そこで本記事では、 shell を使って crontab を設定する方法を紹介します。
コード
下は私が実際に使ったコードを一部修正したものです。
ウェブアプリケーションサーバ、メールサーバの両方で使うことを前提にしています。 シェル実行時に引数で、開発環境・本番環境の別とサーバの用途を渡します。 その情報から crontab で実行するスクリプトの引数を適切に決定して crontab を設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#!/bin/sh # Usage # sh root_setup.sh development application # for development application server # sh root_setup.sh production mail # for production mail server if [ `whoami` != "root" ]; then echo "Execute this script as root user." >&2 exit 1 fi func_help () { echo "== Usage == sh root_setup.sh [environment] [services] sh root_setup.sh -h == Option == -h : show this help == Argument == environment - development or production services - ap or mail == Example == sh root_setup.sh development application sh root_setup.sh production mail == Description == setup root crontab and root script files. " return 0 } while getopts h opt do case $opt in h) func_help exit 0 esac done case $1 in development ) env=development;; production ) env=production;; * ) echo "Set correct environment: development or production" >&2 exit 1 esac case $2 in application ) services=nginx;; mail ) services=saslauthd,postfix;; * ) echo "Set correct server type: application or mail" >&2 exit 1 esac dirPath="`dirname $0`" rootDir="`readlink -f $dirPath/../`" dirPath=$rootDir"/file" # setup monitoring scripts rootScriptDir=$dirPath"/root/monitoring" rootFileDir=$dirPath"/root" rm -rf $rootScriptDir cp -R $dirPath"/monitoring" $dirPath"/root" chmod 755 $rootScriptDir/* # setup crontab logDir="`readlink -f $dirPath/../log`" cronDescription="*/3 * * * * ${rootScriptDir}/service_check.pl $env $services > ${logDir}/service_check.log 2>&1 4 3 * * * ${rootScriptDir}/resource_check.pl $env > ${logDir}/resource_check.log 2>&1 " echo "$cronDescription" | crontab echo "Your root crontab was set to:" echo "$cronDescription" exit 0 |
順に説明します。
実行ユーザを制限
今回は root の crontab 設定用 スクリプト を 考えています。 そのため、 誤って別のユーザでこのスクリプトを実行されるとまずいです。
そこで、 whoami
の返り値から、 実行ユーザが root でなければ終了するようにしています。
実行ユーザが root か否かを判断するには id
コマンド で uid
を調べたほうが ユーザ名が root でない場合でも使えるので確実ですが、 いまのところはそういった凝ったことをする予定はないので whoami
の結果を 文字列 "root"
と比較しています。
ヘルプを表示する関数
もし使い方を忘れたときのために、ヘルプがあると助けになります。 そこで ヘルプ表示用の関数を作ります。
スクリプトの変数に オプション -h
が指定された時は getopts
を利用してヘルプを表示し、 終了するようになっています。
引数の確認
引数を確認します。 引数の値によって、 crontab に記述される内容を変えます。
ディレクトリの文字列を設定
シェルスクリプトで readlink
を使って絶対パスを取得しています。 絶対パスの取得・生成では pwd
と dirname
を組み合わせて使っていくこともできますが、 ..
や .
が出てくると歪な絶対パスになってしまいます、 例えば /abc/def/../hij
のように。
readlink
を使えば そういった ..
などもきれいに消してくれます。
ファイルと権限設定
今回は Perl のスクリプトを crontab で実行するので、 実行用の Perl スクリプトをコピーして、 権限などの操作をしています。
crontab 設定
crontab にする文字列を生成し、 echo "$cronDescription" | crontab
で crontab を設定します。 $cronDescription
をダブルクオートで囲むところが重要で、 これがないと $cronDescription
内 の *
などが 展開され、 意図した crontab の設定ができません。