Friction River Software

  • お問い合わせ

CakePHP5入門【コラム⑨】シェルスクリプト

A子

データベースのバックアップってこうだったよね?
(CakePHP5応用編⑩を参照)

mysqldump -u root -p bbsdb > bbsdb_backup.sql[Enter]

これって、(本番環境のWebサーバにSSH接続して)わざわざ手動で定期的に行うのは面倒くさいんだよねー
なんとか自動化できないかな?

B美

cronクーロンを使えば、好きなタイミングで自動実行できるわよ

C菜

あ、だったら追加で~
バックアップファイルのファイル名に、バックアップ実施日の「年月日」を付け加えることってできますか~?

例えば、2025年3月1日だったら「bbsdb_backup_20250301.sql」みたいな感じで~

B美

もちろん可能よ

そういう場合はシェルスクリプトを書けば良いの

A子

よく分からん単語が二つも出てきたよ…(苦笑)

「くーろん」と「しぇるすくりぷと」って何?

B美

cronクーロンというのはLinux(正確にはUNIX系OS)に備わっている機能で、指定したタイミングで指定したプログラムを実行してくれるってやつよ

シェルスクリプトというのは、複数のコマンドを一つのファイルにまとめておいて、そのファイル名をターミナル上で叩くことでその中の命令が勝手に実行されるって仕組みね
(Windowsのバッチファイルと同じもの…と言って分かるかしら?)

C菜

Excelのマクロ機能みたいなものですか~?

B美

まさにその通り!

どういうスクリプトを書けば良いのかは、「ChatGPT」に聞いてみなさい
(すぐに教えてくれるから…)

A子

聞いてみたよ

#!/bin/sh

# 設定
DB_NAME="bbsdb" # バックアップするデータベース名
DB_USER="root" # MySQLのユーザー名
DB_PASS="xxxxxxxx" # MySQLのパスワード
BACKUP_DIR="/home/bimi/backup/bbsapp" # バックアップ保存先ディレクトリ

# 日付取得 (YYYYMMDD形式)
DATE=$(date +"%Y%m%d")

# バックアップファイル名
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"

# mysqldump を実行してバックアップ
mysqldump -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" > "${BACKUP_FILE}"

# 30日以上前のバックアップを削除
find "${BACKUP_DIR}" -name "${DB_NAME}_*.sql" -mtime +30 -exec rm {} \;

あ、DB_PASS(データベースのrootパスワード)の「xxxxxxxx」は(当然だけど)伏字ね

これをエディターソフトで作って「bbsdb_backup.sh」というファイル名でユーザホーム(/home/bimi)の中に保存したよ
(「bimi」の箇所については、本番環境のほうでは書き換えるけど…)

あと、ユーザホームの直下に「backup」ディレクトリを作って、さらにその中に「bbsapp」ディレクトリを作ったからね
(本番環境は後でやるとして、とりあえずは開発環境だけ…)


C菜

アップロードされた画像ファイルのバックアップはどうしますか~?

A子

おっと、それもあったね

うーん、どうしよう?

B美

複数の画像ファイルをアーカイブ(ZIPファイルに)して、さっきと同じようにバックアップ用のディレクトリに保存しちゃえば良いのよ

A子

ChatGPTに質問してみよう

・・・

うーん
教えてもらったコードの中身を完全には理解できないんだけど、一応書き加えてみたよ

#!/bin/sh

# 設定
DB_NAME="bbsdb" # バックアップするデータベース名
DB_USER="root" # MySQLのユーザー名
DB_PASS="xxxxxxxx" # MySQLのパスワード
BACKUP_DIR="/home/bimi/backup/bbsapp" # バックアップ保存先ディレクトリ
SOURCE_DIR="/home/bimi/html/bbsapp/webroot/files" # 圧縮する画像があるディレクトリ

# 日付取得 (YYYYMMDD形式)
DATE=$(date +"%Y%m%d")

# バックアップファイル名
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql"

# ZIPファイル名
ZIP_FILE="${BACKUP_DIR}/images_backup_${DATE}.zip"


# mysqldump を実行してバックアップ
mysqldump -u "${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" > "${BACKUP_FILE}"

# 画像をZIPに圧縮(jpg, png, gif を対象)
if find "${SOURCE_DIR}" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" \) | grep -q .; then
    find "${SOURCE_DIR}" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" \) | zip -j "${ZIP_FILE}" -@
fi


# 30日以上前のバックアップを削除
find "${BACKUP_DIR}" -name "${DB_NAME}_*.sql" -mtime +30 -exec rm {} \;
find "${BACKUP_DIR}" -name "images_backup_*.zip" -mtime +30 -exec rm {} \;

赤字が追加した箇所ね

B美

ふむ…
大丈夫そうね

C菜

実行してみるです~
「MATE端末」を開いてから、ファイル名を入力してエンターキーで良いんですよね~?

あれ~?
入力をミスってないのに「コマンドが見つかりません」って出ましたよ~

B美

Windowsだったら、そのやり方で良いんだけどね(苦笑)

Linux(正確にはUNIX系OS)の場合は、実行ファイルの前に「./」を付けなきゃいけないのよ
(そういう規則なの)

A子

んじゃ

./bbsdb_backup.sh[Enter]

を叩いてみよう

ん?
今度は「許可がありません」だって…

B美

PHP言語のプログラムは例外なんだけど、本来プログラムファイルには「実行権」が必要なのよ
要するに、パーミッション設定ね

ls -l[Enter]

を実行してみなさい

「r」はread、「w」はwrite、「x」はexecuteで、「オーナー・グループ・その他」の順にそれぞれ三つの要素を指定できるの
(左端の文字については、ファイルは「-」、ディレクトリの場合は「d」ね)

C菜

えっと~

「bbsdb_backup.sh」のパーミッションは「-rw-r--r--」なので~
オーナー(このファイルの所有者)は「読み書き」できて(rw-)、同じグループ内のメンバーとその他の人たちは「読む」ことしかできない(r--)ってことでしょうか~?

B美

C菜、あなたすごいわね
大正解よ

ちなみに「r」は4、「w」は2、「x」は1という数字で表現するので、「-rw-r--r--」は「644」ということになるわ
(「6」は「4+2」ってことね)

A子

あー、前にも出てきてたね、その数字

757」とか「600」とか…
(CakePHP5応用編⑩を参照)

C菜

だったらこうでしょうか~?

chmod 755 bbsdb_backup.sh[Enter]

「644」の各けたに1ずつ足しただけですけど~

B美

OK、OK

それじゃバックアップを実行してみなさい

A子

./bbsdb_backup.sh[Enter]

で良いんだよね?

C菜

ファイルが生成されてます~

A子

ZIPファイルをダブルクリックしてみたけど、複数の画像ファイルが格納されてるのを確認できたよ

B美

次は、このスクリプトが自動的に実行されるようにしましょう
「MATE端末」から

crontab -e[Enter]

を実行してね

あ、一番最初はクーロンテーブルが無いから、「nano」と「vim(vi)」のどっちを使うか聞かれるかも…
(好きなほうを指定すれば良いんだけど、ここでは「nano」で説明するわ)

B美

左端に「#」が付いている行はコメント行ね

で、一番下にサンプルがあるんだけど…

0 5 * * 1 tar -zcf /var/backups/home.tgz /home/

の意味は、「毎週月曜日の午前5時ちょうどにtarコマンドを実行する」ってわけ
つまり、左から「分 時 日 月 曜日 実行するコマンド」ということね

なお、曜日は数字で表すんだけど「日…0,月…1,火…2,水…3,木…4,金…5,土…6」だからね

A子

んー、ってことは…
毎日午前2時にバックアップを実行したければ

0 2 * * * ./bbsdb_backup.sh

ってことかな?

B美

その書き方じゃ、cronクーロンからそのファイルを見ることができないかもしれないわね

指定するシェルスクリプトは、必ず「絶対パス」で記述すること!

C菜

でしたら、こうでしょうか~?

0 2 * * * /home/bimi/bbsdb_backup.sh

B美

正解よ

あ、本番環境では「bimi」の箇所は適宜変更してね
(「bbsdb_backup.sh」の中に二ヶ所ある「bimi」の部分についても、忘れずに変更すること)

A子

分かったよ

それにしても、B美先生とChatGPTがいなけりゃどうなっていたことやら…(苦笑)

C菜

ほんとですよ~