第8回kintoneコマンドラインツール(cli-kintone v0)のバックアップ処理を定期実行してみよう

著者名: 瀧ヶ平 充 (External link)

目次

information

このチュートリアルはver. 0.x.xのcli-kintoneの使い方を紹介しています。
ver.1.0.0以降のcli-kintoneの使い方を紹介するチュートリアルは次のページを参照してください。
はじめようcli-kintone

はじめに

こんにちは、前回は第6回での操作をシェルスクリプト化しました。

今度は前回作成したシェルスクリプト「kintone-backup.sh」を定期的に実行させるため、Mac環境では「Launchd」を、CygwinおよびLinux環境では「cron」を設定していきます。
また、定期実行と合わせて、エラーログを出力できるようにシェルスクリプトを編集していきます。

処理をスケジューリングする

各環境ごとに準備が異なるため、まずはそれぞれの環境で準備をしましょう。

macOSの設定

ここではLaunchdを利用した定期実行設定の概略を参考として紹介します。

はじめに、実行内容をXMLで指定するlaunchd.plistを作成します。
ファイル名は任意に決めて問題ありませんが、今回は「kintone-backup.daily.plist」というファイル名で作成します。

以下、毎月10日の11時00分にバックアップを実行する場合の例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>kintone-backup.dailyjob</string>
    <key>ProgramArguments</key>
    <array>
        <!-- バックアップ用シェルスクリプトへのパス -->
        <string>/path/to/kintone-backup.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <!-- 実行時刻の指定 -->
        <key>Day</key>
        <integer>10</integer>
        <key>Hour</key>
        <integer>11</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
</dict>
</plist>

以下のパスは「kintone-backup.sh」へのパスに置き換えてください。

1
2
        <!-- バックアップ用シェルスクリプトへのパス -->
        <string>/path/to/kintone-backup.sh</string>

「kintone-backup.daily.plist」の編集が終わったら、下記ディレクトリに配置します。

1
2
# kintone-backup.daily.plistを指定のディレクトリに配置
cp kintone-backup.daily.plist ~/Library/LaunchAgents/

配置が完了したら、launchdに作成したファイルを登録します。

1
2
# launchdへ登録
launchctl load ~/Library/LaunchAgents/kintone-backup.daily.plist

ここまでで定期実行の設定は完了です。

ここでは概略のみ説明しましたが、launchd.plist作成方法の詳細は 公式ドキュメント (External link) を参照してください。

Cygwin

Cygwin上でcronを使う場合、cygrunsrvというコマンドをCygwin上で実行します。
croncygrunsrvコマンドが入っていない場合はCygwinの「setup.exe」から追加インストールしてください。

このときCygwinのbashはWindowsの管理者権限で実行する必要があります。

1
cygrunsrv -l cron -p /usr/sbin/cron -a -D

これでOSの起動時に自動でcronサービスが実行されます。手動でcronを開始したい場合は末尾に-t manualをつけて実行してください。

手動でcronを起動する場合は、次のコマンドを実行します。

1
cygrunsrv -S cron

Linux

Linuxでは各ディストリビューションで状況が異なります。
ここでは執筆時点での最新版(Cent OS7、RHEL7以降およびUbuntu v15.04以降)での設定方法を紹介します。
それ以前のバージョンの場合は実行方法が異なるので、必要に応じてそれぞれ調べてください。

これらのOSの場合はSystemdを利用しているので、systemctlコマンドでcrondサービスを起動します。

この操作にはスーパーユーザ権限が必要です。
次のどちらかを実施してから、コマンドを実行してください。

  • rootユーザで実行する。
  • コマンドを実行する一般ユーザーにroot権限を付与する。
    権限を付与するには、システム管理者にvisudoコマンドを使って現在のユーザを「/etc/sudoers」へ追加してもらった上で、sudoをつけます。
1
2
3
4
5
# rootユーザー で実行する場合
systemctl start crond

# 一般ユーザでsudo実行する場合
sudo systemctl start crond

システムの起動時サービスを起動するには、次のコマンドを実行します。
一般ユーザで実行する場合はさきほどと同様にsudoをつけて実行します。

1
2
3
4
5
# rootで実行する場合
systemctl enable crond

# 一般ユーザでsudo実行する場合
sudo systemctl enable crond

サービスの実行状態は、下記コマンドで確認できます。

1
systemctl status crond

cronジョブの追加

Mac以外を利用している方はcronの設定をしていきましょう。
cronで定期実行されるタスク(スクリプト)は「ジョブ」と呼ばれます。実行対象となるジョブの一覧を編集するには、次のコマンドを実行します。

1
crontab -e

このとき、crontabは環境変数EDITORに格納されているパスのコマンドラインエディタを利用します。
定期実行ジョブの編集を始める前に、コマンドラインエディタについて確認してみましょう。

環境変数EDITORの設定

cronジョブの編集に使用するエディタは、下記コマンドを実行して設定できます。

1
export EDITOR=$(which vim)

コマンドラインで使えるエディタにはnano、EmacsやVimなどありますが、今回はVimの利用を想定して説明しています。
もしVimがインストールされていない場合は、Vimをインストールしておいてください。
また、他のエディタを使いたい方は、次の要領で環境変数を設定してください。

1
export EDITOR=<使うコマンドラインエディタのパス>

Vimの操作

Vimはノーマルモード/挿入モード/選択モードの3つのモードがあるエディタです。

基本操作

起動時のVimはノーマルモードになっています。
Iキーでカーソルの左側からの挿入モードへ切り替え、Aキーでカーソルの右側からの挿入モードへ切り替えが可能です。
挿入モードからはEscキーやCtrl+[でノーマルモードへ切り替えられます。

ノーマルモードでは矢印キーか、H J K Lキーでそれぞれ左/下/上/右へのカーソル移動が可能です。
この他のキー(あるいはキーの組み合わせ)にもいろいろな機能が割り当てられているので、 Vim Cheat Sheet (External link) などで覚えると便利です。

コマンド実行モードとショートカット

ノーマルモードでは、:で始めると、コマンドを入力・実行できる機能があります。
挿入モードではVim特有のショートカットによる機能(キーバインド)を利用できます。

ファイルの保存とVimの終了

ファイルを開くときはノーマルモードで:eファイルへのパスを入力してからEnterキーで確定し、保存するときは:wを入力してからEnterキーで確定します。
終了する場合は、ノーマルモードのときに:qを入力します。

cron設定の書き方

cronで定期実行するジョブの一覧を編集するには、下記コマンドを実行します。

1
crontab -e

このまま実行すると作業しているユーザがジョブの実行ユーザになります。
ジョブを実行するユーザを指定するには、次のコマンドを実行します。

1
crontab -e USERNAME

cronの設定は各行ごとにスペース区切りで書きます。
Vimを使う場合は、目的の位置にカーソルを移動した後、iまたはaで挿入モードに移行しましょう。

1
分 時 日 月 曜日 コマンド

曜日は0から6までの数字で表現します。
日曜始まりなので、日曜日が0で、月曜日が6です。
また、このとき設定しない項目は*で埋めます。

たとえば、毎月10日の11時00分に「kintone-backup.sh」を実行する場合、次のように記述します。

1
00 11 10 * * /path/to/kintone-backup.sh

/path/to/kintone-backup.shの部分は「kintone-backup.sh」へのパスに置き換えてください。

設定を書き終えたら、次の順に操作して、ファイルの保存とVimの終了を実施します。

  1. EscまたはCtrl-[でノーマルモードに移行する。
  2. :wでファイルを保存する。
  3. :qでVimを終了する。

実行時のエラーログ

自動で実行されるのはうれしいですが、シェルスクリプトの実行に成功したか失敗したかなどの情報が確認できないと、運用時に困ることがあります。
そこで、簡易的にエラーログを出力できるよう、シェルスクリプトを編集していきましょう。 シェルスクリプトの処理の内容については 第7回を参照してください。

シェルスクリプトファイルを編集した場合、 処理をスケジューリングするで設定したパスにシェルスクリプトを再配置することを忘れないようにしましょう。

エラーロギングの準備

まず、エラーが発生したらシェルスクリプトを中断するようにします。

bashの-eオプションをつけた状態でシェルスクリプトを実行すると、実行後ステータスが「0」でない場合、つまりコマンド実行が失敗したらシェルスクリプトを終了できます。

そのため、 第7回で宣言したshebangを次のように書き換えます。

1
#!/bin/bash -e

次に、エラーログを記録するファイルのパスを変数に格納します。

1
errorLog=エラーログのパス

実行日時の印字

実行日をわかるようにするため、ログの頭にdateコマンドを使って日付を印字します。

1
date >> $errorLog

エラー出力のリダイレクト

エラー出力にはシェルのリダイレクト機能を利用します。

2> ファイル名というように出力先を変更すると、エラー出力のみを指定のファイルに書き出すことができます。これを利用して簡易的なエラーログのしくみを実装します。

2>>という形にすれば、エラーメッセージをファイルに追記する形でリダイレクトしてくれるので、こちらも使います。

パイプライン処理がない場合

今回はレコードのcli-kintoneを実行するたびにエラーログを出力するように変更します。

パイプライン処理をしていない実行コマンドの場合は、2>> $errorLogスクリプトの末尾に追記します。

1
cli-kintone --import -d $outputDomain -a $outputApp -t $outputToken -f $backupFile -b $attachmentDir

この実行コマンドの場合、以下のように書き換えます。

1
cli-kintone --import -d $outputDomain -a $outputApp -t $outputToken -f $backupFile -b $attachmentDir 2>> $errorLog
パイプライン処理がある場合

パイプライン処理のある実行コマンドの場合、cli-kintoneの実行コマンドの行の|の直前に2>> $errorLogを追加します。

1
cli-kintone --export -d $inputDomain -a $inputApp -t $inputToken -b $attachmentDir -q '\$id > $lastRecordId' | sed "1 s/\$id/record_id/" > $backupFile

この実行コマンドの場合、以下のように書き換えます。

1
cli-kintone --export -d $inputDomain -a $inputApp -t $inputToken -b $attachmentDir -q '\$id > $lastRecordId' 2>> $errorLog | sed "1 s/\$id/record_id/" > $backupFile

書き換え後全体のシェルスクリプト

ここまでに紹介してきたエラーログ追加の変更を、シェルスクリプト全体に反映させましょう。

 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
#!/bin/bash -e

inputDomain=<バックアップ元アプリのドメイン>
inputApp=<バックアップ元のアプリID>
inputToken=<バックアップ元のAPIトークン>
outputDomain=<バックアップ先アプリのドメイン>
outputApp=<バックアップ先のアプリID>
outputToken=<バックアップ先のAPIトークン>
attachmentDir=<添付ファイルを保存するディレクトリ>
backupFields=<バックアップするフィールド(カンマ区切り)> # ここには必ず $idを含めるようにしてください
backupFile=<新規レコードバックアップ用CSVファイルへのパス>
syncFile=<既存レコード更新用CSVファイルへのパス>
errorLog=<エラーログのパス>
export PATH="$PATH:<cli-kintoneのあるディレクトリ>"

# 実行日時の印字
date >> $errorLog
echo >> $errorLog

# バックアップ済最新のレコードID
lastRecordId=$(cli-kintone --export -d $outputDomain -a $outputApp -t $outputToken -c "record_id" -q "order by record_id desc limit 1" 2>> $errorLog | sed "1 d")
if [ -z "$lastRecordId" ]; then
    lastRecordId=0
fi

# 新規にバックアップ
# バックアップ元からエクスポート
cli-kintone --export -d $inputDomain -a $inputApp -t $inputToken -b $attachmentDir -q "\$id > $lastRecordId order by \$id asc" 2>> $errorLog | sed "1 s/\$id/record_id/" > $backupFile

# バックアップ先へインポート
cli-kintone --import -d $outputDomain -a $outputApp -t $outputToken -f $backupFile -b $attachmentDir 2>> $errorLog

# レコードの同期
# バックアップ元からエクスポート
cli-kintone --export -d $inputDomain -a $inputApp -t $inputToken -b $attachmentDir -q "\$id <= $lastRecordId order by \$id asc" 2>> $errorLog | sed "1 s/\$id/\*record_id/" > $syncFile

# バックアップ先へインポート
cli-kintone --import -d $outputDomain -a $outputApp -t $outputToken -f $syncFile -b $attachmentDir 2>> $errorLog


# 実行日時の印字
echo >> $errorLog
date >> $errorLog

こうすることで、エラーが発生した場合も途中で処理を中止し、ログを残すことが可能です。

ここではエラーを単一のログファイルに出力していますが、date -Iとコマンド置換を用いてファイル名を決めれば、日付ごとにエラーログを分けることもできますね。

すでにcronやLaunchdで定期実行の設定をしているので、今回はこれで完了です。
動作確認は、設定日時まで待つか、一時的に実行時刻を5分後などに設定して行うとよいでしょう。

まとめ

以上で第8回は終了です。

難しいコマンドライン操作でしたが、いかがでしたか?
次回もお楽しみに。

information

このTipsは、cli-kintone ver 0.10.2と2020年3月版kintoneで動作を確認しています。