診断ドットコムのSNSを是非フォローお願いします☆X(Twitter) TwitterThreads Threadsタイッツーロゴ タイッツーmisskeyロゴ Misskey

ブログトップ > Cronからシェルスクリプト経由でphpを実行する方法[XSERVERでバッチ処理]

Cronからシェルスクリプト経由でphpを実行する方法[XSERVERでバッチ処理]

こんにちは、Kotoriです。
Kotoriは資産運用会社に勤めていて営業部なのですが、何故か業務は完全にシステム系です。
システム開発のプロジェクトマネージャーやシステム運用の主担当です。
元々はWebデザイナーだったのであまりシステム周りは得意ではなくここ3~4年で色々経験したのですが、最近ようやくバッチ処理の意味とシェルスクリプトの存在意義を理解しました。

折角理解したので、実践として自作で一本バッチ処理を作ってみました。処理内容は凄く簡単で、Twitter APIを利用し特定のキーワードが含まれるツイートをjsonファイルに書き出すだけです。ツイートをjsonファイルに書き出すプログラミング自体は簡単だったのですが、バッチ処理として定期的に動作させるまでにもの凄く苦労したので、他の人が同じ事で迷わないようバッチ処理を作成する手順を詳しくブログ記事にしたためたいと思います。

バッチ処理とは

私も最近までよく意味が分かっていなかった「バッチ処理」という言葉を説明したいと思います。
バッチ処理とは
特定のタイミングでまとめてやる処理
のことです。

例え話をしましょう。
会社で経費申請をするときの事を想像してください!例えば外で打ち合わせがあった時、移動のための交通費が発生します。電車にしろタクシーにしろ普通は一時的に本人が建て替えて後で経費申請を行い清算すると思います。
ここで質問です。
あなたは経費を建て替えたその都度申請しますか?
それとも月末など特定のタイミングにまとめて申請しますか?

几帳面な方は都度申請するでしょう。Kotoriみたいに大ざっぱな方は限界まで溜め込んで暇な時間帯をみつけてまとめて申請するでしょう。
この場合の後者「特定のタイミングにまとめて申請する」がバッチ処理にあたります。
ある程度データをため込んで特定のタイミングで一気に処理する!これがバッチ処理です。

実際のシステムで考えると、月末の清算処理やデータのバックアップなどリアルタイム性を要さず特定のタイミングでまとめて実行したほうが効率が良い処理は、バッチ処理が有効です。
バッチ処理のメリットとして処理が走る時間を自由に設定できることが挙げられます。
よくあるのは、アクセス数が少なく負荷が少ないため深夜にバッチ実行の時間を設定することです。いわゆる深夜バッチですね。まぁ深夜バッチがコケるとそれはそれで大変なのですがその話はまた今度笑

因みにバッチ処理とは逆に、経費を建て替えた都度、経費申請するような処理は「API」と言ったりします。
「API」の場合は、処理が発生する都度APIリクエストを投げリアルタイムに処理を行います。

システム関係の業務だと、よく「バッチ処理」か「API」かで議論になるので知らなかった人は是非覚えておきましょう。

環境

この記事では下記の環境でバッチ処理を作成します。

バッチ処理の流れ XSERVERに設定したCronからシェルスクリプト経由でphpを実行する
プログラム言語 PHP、シェルスクリプト
サーバー XSERVER
作業PCのOS Windows
サーバーへのSSH接続ソフト winSCP

Cronからシェルスクリプト経由でphpを実行する手順

そもそもバッチ処理はどのように実装すればよいのかKotoriは最近まで全くイメージが湧いていませんでしたが、最近やっと分かりました。
バッチ処理とは以下のイメージです!

1.定期的に実行したい処理をphpでプログラミングする
2.そのphpを実行するための処理をシェルスクリプトで実装する
3.そのシェルスクリプトをCronで定期的に実行する
(どのプログラミング言語で実装するかは人それぞれあると思うので適当に読み替えてもらえればと思います!)

この理解に至るまで3~4年掛かりました笑 誰も教えてくれる人がいなかったからです。
それはさておき、この流れに沿ってバッチ処理を作成する手順を、めちゃくちゃ詳しく説明したいと思います。

まずはphpで定期的に実行したい処理をプログラミング

まずは定期的に実行したいファイルが無いとバッチ処理は始まりませんね。冒頭でも触れましたが、この記事ではTwitter APIを利用し特定キーワードを含むツイートを取得しjsonファイルに書き出すという処理をphpで実装しました。

一応プログラムを載せておきます。
ファイル名は「batch.php」とします。

define('TWITTER_API_KEY', '●●●●●●●●●●●●●●●●●●●●●●'); //Consumer Key (API Key)
define('TWITTER_API_SECRET', '●●●●●●●●●●●●●●●●●●●●●●');//Consumer Secret (API Secret)

// twitteroauth の読み込み
require_once $fullpath.'vendor/autoload.php';
use Abraham\TwitterOAuth\TwitterOAuth;

//Twitterのコンシュマーキー(APIキー)等読み込み
require_once $fullpath.'part/oauth-config.php';


//TwitterOAuthのインスタンスを生成し、Twitterからリクエストトークンを取得する
$connection = new TwitterOAuth(TWITTER_API_KEY, TWITTER_API_SECRET, null, null);

//$statuses = $connection->get("search/tweets", ["q" => "4ndan.com","count" => 15,"tweet_mode" => "extended"]);
$statuses = $connection->get("search/tweets", ["q" => "appli-maker","count" => 15,"tweet_mode" => "extended"]);

$statuses = json_encode($statuses, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
file_put_contents("tweets.json" , $statuses);

このプログラムはTwitter APIへの接続に「abraham/twitteroauth」というライブラリを利用しています。
「abraham/twitteroauth」のインストール方法はこの記事をご覧ください。
2019年!Composerのインストール方法と使い方![twitteroauthをインストール]

まぁバッチ処理を試すだけなら適当な文字列をjsonに吐き出すようなプログラムにでも書き換えてください。
phpファイルが作成できたらサーバーにアップして正常に動作するか確認しましょう。

XSERVERでシェルスクリプトを実行するためWindowsからWinSCPでSSH接続を行う

続いてシェルスクリプトの作成を行うのですが、その前にサーバー上でシェルスクリプトを実行するためにはSSH接続しなければいけません。
そのため、XSERVERにSSHで接続する方法から確認していきましょう。XSERVERへの接続はFTPソフト「winSCP」を利用します。

XSERVERでSSH接続を有効にする

XSERVERではデフォルトの設定でSSH接続がOFFになっているためSSH接続を有効化してあげる必要があります。この作業はめちゃくちゃ簡単です。

XSERVERの「サーバーパネル」にログインし「アカウント」の「SSH設定」を選択します。
XSERVERの「サーバーパネル」にログインし「アカウント」の「SSH設定」を選択しているスクショ

デフォルトではSSH設定の状態が「OFF」となっているので「ONにする」を選択します。
デフォルトではSSH設定の状態が「OFF」となっているので「ONにする」を選択しているスクショ

「SSH設定の変更を完了しました。」と表示されれば完了です。
「SSH設定の変更を完了しました。」と表示されているスクショ

SSH接続するための公開鍵と秘密鍵のペアをWinSCPの「PuTTY Key Generator」で作成

SSH接続するためには公開鍵と秘密鍵のペアが必要です。
公開鍵はサーバーに登録し、秘密鍵は自分のパソコンに保存します。
サーバーにSSH接続を行う際にサーバーに登録された公開鍵と自分のパソコンの秘密鍵のペアに設定されたパスフレーズを入力することでSSH接続が行えます。

この公開鍵と秘密鍵をWindowsユーザー御用達のFTPソフト「winSCP」にインクルードされている「PuTTY Key Generator」で生成します。
まだwinSCPをインストールしていない人はWinSCPの窓の杜ページ等からインストールしてください。

インストールしたら起動し「機能」を選択し「PuTTY Key Generator」を選択します。
「PuTTY Key Generator」を選択しているスクショ

「Generate」を選択します。
「Generate」を選択

「PuTTY Key Generator」ダイアログ内でマウスをぐりぐり動かします!すると緑のシークバーが溜まっていきます!
「PuTTY Key Generator」ダイアログ内でマウスをぐりぐり動かしてください

シークバーが最後まで溜まったら公開鍵と秘密鍵が出来上がります。
「Key passphrase」と「Confirm passfhrase」にパスフレーズを入力します。このパスフレーズはSSH接続の度に必要になるので忘れないようにメモしておきましょう。
次に「Save private key」ボタンをクリックし拡張子がppkの秘密鍵ファイルを自分のパソコンに保存します。
秘密鍵の保存が終わったら「Public key for pasting into OpenSSH authorized__keys file」の文字列を漏れなくコピーします。
「Key passphrase」と「Confirm passfhrase」にパスフレーズを入力

XSERVERの管理画面に戻り、SSH設定にある「公開鍵登録・設定」タブを選択しコピーした公開鍵をテキストエリアにペーストして「確認画面へ進む」を選択し登録します。
XSERVERの管理画面のSSH設定にある「公開鍵登録・設定」の「公開鍵」テキストエリアに公開鍵をコピペ

XSERVERの「公開鍵登録・設定」タブで公開鍵を登録できたら秘密鍵と公開鍵の用意は完了です。

WinSCPでXSERVERにSSH接続する

先ほど用意した公開鍵と秘密鍵と設定したパスフレーズを使ってWinSCPからXSERVERにSSH接続をします。

WinSCPを起動し「新規」を選択します。
WinSCPを起動し「新規」を選択

各項目を入力します。
「ファイルプロトコル」はSFTPです。(KotoriはこれをSCPにして30分くらいハマってました笑)
「ポート番号」は10022です。
「ホスト名」「ユーザー名」「パスワード」は普段FTP接続する時の情報をそのまま入力してください。(Kotoriは「パスワード」にFTPパスワードではなく先ほど容易した公開鍵と秘密鍵の「パスフレーズ」を入力して30分くらいハマってました笑)
「秘密鍵」は先ほど自分のパソコンに保存した拡張子がppkの秘密鍵ファイルを指定します。
WinSCPの各項目を入力

入力が済んだら「ログイン」を選択すると「パスフレーズ」を求められます。先ほど「PuTTY Key Generator」で設定した「パスフレーズ」を入力し「OK」を選択しましょう!
「パスフレーズ」を入力し「OK」を選択

正常にアクセルできればSSH接続の完了です!

XSERVERでシェルスクリプトのコマンドを入力からphpファイルを実行する

XSERVERにSSH接続できたらいよいよシェルスクリプトの出番です。
実行したいphpファイルはXSERVER上にアップしてある前提で話を進めます。

まずはシェルスクリプトからbatch.phpを実行できるようbatch.phpのパーミッションの設定を変更します。
WinSCPでサーバーにアクセスしている状態で、サーバー上の「batch.php」を右クリックし「プロパティ」をクリックします。
WinSCPでサーバーにアクセスし「batch.php」を右クリックし「プロパティ」をクリック

パーミッションの「所有者」の「X」にチェックを入れましょう。X=実行権限なので所有者に実行権限を付与し、シェルスクリプトからbatch.phpを実行できるようにします。
パーミッションの「所有者」の「X」にチェック

XSERVERにSSH接続してシェルスクリプトのコマンドを入力するために、「コンソール」を立ち上げる必要があります。
WinSCPでXSERVERにSSH接続した状態で「コンソール」ボタンを選択してみましょう。
WinSCPでXSERVERにSSH接続した状態で「コンソール」ボタンを選択

確認のダイアログが表示されるので「OK」を選択します。すると再度「パスフレーズ」を求められるので入力し「OK」を選択します。
すると「コンソール」が立ち上がります。
「コンソール」が立ち上がる

この画面でシェルスクリプトのコマンドを一行ずつ打ち込んでいきます。
phpを実行するだけであれば、基本は「cd フォルダパス」コマンドで実行したいphpファイルが存在するフォルダまで移動し、phpを実行するコマンドを入力します。
見ていきましょう。

まずは「cd フォルダパス」コマンドで実行したいphpファイルが存在するフォルダまで移動します。
コマンドを入力して「実行」ボタンを選択します。
「cd フォルダパス」コマンドを入力し実行
具体的なコードも載せておきます。(xxxは自分のフォルダ名に置き換えてください)

cd /home/xxxxxxx/xxxxxxxxx/public_html/xxxxxxx

上記コマンドを実行した後に「現在のディレクトリ」が実行したいphpファイルが存在するフォルダになっていればOKです。

続いてphpを実行するコマンドを入力します。具体的なコマンドは下記の通りです。

/usr/bin/php7.2 ./batch.php

「php7.2」となっている部分は、使用しているphpのバージョンによってコマンドが変わります。詳しくはプログラム言語・コマンドパスを確認してください。

batch.phpが正常に実行されていればOKです。batch.phpの処理はjsonファイルへの書き込みなため当該jsonファイルの更新日時を確認すればシェルスクリプトからbatch.phpを実行できたかどうかを確認できます。

シェルスクリプトのコマンドをファイル化(拡張子 .sh)

シェルスクリプトのコマンドからbatch.phpを正常に実行できたら、そのコマンドをファイル化します。拡張子は.shです。
ただ、Windows環境で.shファイルを作成する場合は注意が必要です。XSERVER等のLinux環境とWindows環境では改行コードが違います。
そのためWindowsのメモ帳などで、シェルスクリプトのコマンドを入力し保存すると、XSERVERで実行した時にエラーが表示されることになります。

具体的には、Windowsは改行コードは「CR+LF」ですがLinuxは「LF」です。Windows環境で作られた.shファイルに改行が入るとLinuxは「CR」を文字列と解釈してしまうため.shファイル実行時に下記のようなエラーが表示されます。
改行コードの違いからエラーが表示される

Windows環境でシェルスクリプトのコマンドを記述した.shファイルを作成するなら、サクラエディタや秀丸エディタ等を利用し改行コードを「LF」で保存してください。

ということで、お使いのテキストエディタでbatch.phpファイルを実行できた時のコマンドを記述し改行コードを「LF」にして拡張子を「.sh」で保存してください。

cd /home/xxxxxxx/xxxxxxxxx/public_html/xxxxxxx
/usr/bin/php7.2 ./batch.php

保存した「.sh」ファイルはXSERVERにアップしましょう。
以降、「.sh」ファイルはbatch.phpファイルと同じ階層にアップしたとします。

「.sh」ファイルをサーバーにアップしたらCronから実行できるように忘れずにパーミッションを設定しましょう。
WinSCPでサーバーにアクセスした状態で、サーバー上の「.sh」ファイルを右クリックの「プロパティ」から「パーミッション」の「所有者」の「X」にチェックを入れます。
パーミッションの「所有者」の「X」にチェック

これでシェルスクリプトの仕込みも完了です。

XSERVERのCron設定によりシェルスクリプト経由でphpファイルを定期的に実行する

いよいよXSERVERのCron設定で定期的にphpファイルを実行できるようにします。

XSERVERのサーバーパネルにログインし「アカウント」の「Cron設定」を選択します。
XSERVERの「サーバーパネル」にログインし「アカウント」の「Cron設定」を選択しているスクショ

「Cron設定追加」を選択し各項目を入力します。
例えば5分毎に実行したい場合は下記のような入力内容になります。
「コマンド」には先ほど作成した「.sh」ファイルへのフルパスを入力します。
「コメント」は任意のコメントを入力します。
Cron設定の例

「確認画面へ進む」を選択し登録できたら作業完了です。
ちゃんと実行されるか5分後に確認してみましょう。

Cronからシェルスクリプト経由でphpを実行する方法のまとめ

初心者でもWindows環境とXSERVERでphpとシェルスクリプトを利用したバッチ処理を構築できるように1からめちゃくちゃ詳しく解説しました。
Kotoriはこの全貌を理解するまで3~4年掛かりましたが、当時このような記事に出会っていたらもっと早く理解できていたのではないかと思います。
自分が理解が遅れた分、ブログ記事に残すことで誰かの理解が少しでも深まってくれればといった気持ちです。

バッチ処理を構築できるようになると、実装の幅がグッと広がるので覚えておいて損は無いと思います。

ここまで読んでいただきありがとうございました!

2019.4.20
TOPへ