LoginSignup
0
1

More than 5 years have passed since last update.

コンピュータ将棋ソフトとの対局サーバーを立てよう<その3>

Last updated at Posted at 2017-03-07

前回の記事 : http://qiita.com/muzudho1/items/bf3f6debf6db7f96300c#_reference-bfc60da48dec57f06190

bash で無限ループはどう書くのか

試しに直接叩いてみる。

./loop8.sh
-su: ./loop8.sh: Permission denied

これは実行ファイルじゃないのか。あるいは実行権限がいるのか。

ls -an
~中略~
-rw-r--r-- 1 0 0  104 Mar  7 20:52 loop8.sh
chmod 755 loop8.sh
ls -an
~中略~
-rwxr-xr-x 1 0 0  104 Mar  7 20:52 loop8.sh
./loop8.sh

これでブロックされた。

[Ctrl]+[Z]

^Z
[1]+  Stopped                 ./loop8.sh
jobs
[1]+  Stopped                 ./loop8.sh

直接実行すると、jobs にいるようだ。php は直接実行じゃないからダメなのか?

nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &
[2] 22501
jobs
[1]+  Stopped                 ./loop8.sh
[2]-  Running                 nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &

今度は後ろで走っているようだ。さっきは走ってなかった気がするが。

一般ユーザーに切り替えよう

su ★user
jobs
ps
  PID TTY          TIME CMD
21573 pts/1    00:00:00 bash
21955 pts/1    00:00:00 php
22536 pts/1    00:00:00 bash
22546 pts/1    00:00:00 ps

ジョブは空っぽだが、プロセスには bash が2つある。 php もあるが……。

$exit
exit
# jobs
[1]+  Stopped                 ./loop8.sh
[2]-  Running                 nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &

exit と打つと exit と返ってくるのか。まぎらわしいな。
スーパーユーザーに戻ってくると、job が見えた。ユーザーによって見える job が異なるのか。

bg 1
[1]+ ./loop8.sh &
jobs
[1]-  Running                 ./loop8.sh &
[2]+  Running                 nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &

bg 1 コマンドで 止まっているジョブを バックグラウンドで走らせることができるのも分かる。

# exit
logout
$ su ★user
Password:
$ jobs
$ exit
exit
$ jobs
[1]+  Running                 nohup /usr/bin/php /home/★user/shogi/php_receive/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &

あれ? バックグラウンドで走っていった方は消えた。 nohup 忘れか。

bg コマンドで nohup なんかできるのか? わからない。

kill %1

別の一般ユーザーを変えて、元のスーパーユーザーに戻ってきたときに job がまだ残っているのは分かった。
じゃあ、スーパーユーザーを抜けて、もう一度スーパーユーザーで入ったときはどうか?

$ su ★user
Password:
$ sudo su -
[sudo] password for ★user:
nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &
[1] 22897
jobs
[1]+  Running                 nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &
ps
  PID TTY          TIME CMD
22468 pts/1    00:00:00 loop8.sh
22501 pts/1    00:00:00 loop8.sh
22849 pts/1    00:00:00 su
22866 pts/1    00:00:00 sudo
22867 pts/1    00:00:00 su
22868 pts/1    00:00:00 bash
22897 pts/1    00:00:00 loop8.sh
22898 pts/1    00:00:00 sleep
22899 pts/1    00:00:00 sleep
22902 pts/1    00:00:00 sleep
22909 pts/1    00:00:00 ps
# exit
logout
$ sudo su -
# jobs
# ^C ※打ち間違い
# ps
  PID TTY          TIME CMD
22468 pts/1    00:00:00 loop8.sh
22501 pts/1    00:00:00 loop8.sh
22849 pts/1    00:00:00 su
22897 pts/1    00:00:00 loop8.sh
22914 pts/1    00:00:00 sleep
22915 pts/1    00:00:00 sleep
22918 pts/1    00:00:00 sleep
22921 pts/1    00:00:00 sudo
22922 pts/1    00:00:00 su
22923 pts/1    00:00:00 bash
22942 pts/1    00:00:00 ps

空っぽ。うーむ。

exit、ログアウトしてはいけないのでは?

exit すると プログラムは終了するということか?
exit とログアウトは違うのか?

「logoutとexitの違い」 (しょぼんメモリ (´・ω・`))
http://shobon.hatenablog.com/entry/2014/06/27/212224

次から logout を使ってみよう。exit は使わない方向で。

exitを使わず、logout でやり直してみる

まず exit を叩きまくって サーバーから抜ける。

次に一般ユーザーで入り直す。

$ jobs
$ ps
  PID TTY          TIME CMD
23342 pts/2    00:00:00 bash
23355 pts/2    00:00:00 ps

次にスーパーユーザーになる。

$ sudo su -
※パスワード入力
# nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &
[1] 23422
# jobs
[1]+  Running                 nohup /home/★user/shogi/bash_receive/loop8.sh > /home/★user/shogi/bash_log/loop8.out.log 2> /home/★user/shogi/bash_log/loop8.err.log < /dev/null &

ここでログアウト。

# logout
$ sudo su -
# jobs

からっぽだ。ユーザーをチェンジすることはよくあるので、exit でも logout でもシェルが止まってしまうようでは サーバー・アプリケーションを開設することができない。

じゃあ、アパッチはどうやって常駐しているのか?

「LAMP構成が基本らしい」 (○×(まるぺけ)つくろーどっとコム)
http://marupeke296.com/IKDADV_SVR_LAMP.html

リモートからセッションきったら なんでジョブが消えるのか?

「Linuxでログアウトやターミナルを切断してもコマンドを続行させる方法」 (小粋空間)
http://www.koikikukan.com/archives/2015/11/20-011111.php

バックグラウンドで動いているジョブがあって、ターミナルからセッションを切ると消える。

logout
sudo su -

のどちらかに問題があるのだろうか。

su ★user でもう1回入って logout。

$ logout
bash: logout: not login shell: use `exit'

うーむ。

su ★user で入ったら、シェルへのログインではないから exit で抜ける??

exit で同じユーザーに戻ってきても、jobs は残っている。

「su ユーザー名」は、何をするコマンドなのか?

「【 他のユーザーでログインし直す 】」 (ITpro)
http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231081/

su の後ろに ‐ がいるのだろうか?

PuTTY を閉じるには?

[Alt]+[F4]キーでも、セッションを切るようだが。

接続すると、jobs は空っぽになっている。

job はセッション・スコープなんだろうか?
アプリケーション・スコープは無いんだろうか?

nohup は使わなくてもいい?

「Linuxのコマンドについて "nohup (プログラム」 (YAHOO!JAPAN知恵袋)
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11164890521

じゃあ

# /usr/bin/php /home/★user/shogi/php_receive/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &
[1] 24330
# jobs
[1]+  Running                 /usr/bin/php /home/★user/shogi/php_receive/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &
$ sudo su -
# jobs

空っぽ。

ターミナルからログアウトすると、なんで バックグラウンドのジョブが消えるんだ?
ユーザーを切り替えた時点で消えるんだろうか?

PuTTY

「Running a Process in the Background with Putty Closed」 (http://linux.ittoolbox.com)
http://linux.ittoolbox.com/groups/technical-functional/linuxadmin-l/running-a-process-in-the-background-with-putty-closed-5205477

  • さくらVPS
  • Linux
  • Ubuntu
  • Bash
  • PuTTY

これ以外に原因があるんだろうか?

ターミナルから実行したものは、ターミナルからログアウトしたら終了する

知ってる人に聞いてみた。そうなのか。
じゃあ設定ファイルでも作って 置いておいて、cron に自動実行させてみよう。

1回蹴ってもらうだけでいいんだが、cron なら コケていても叩き起こしてくれるんじゃないか。

Ubuntu で cron を使うには?

「How do I set up a Cron job?」 (ask ubuntu)
http://askubuntu.com/questions/2368/how-do-i-set-up-a-cron-job

/etc/ ディレクトリに

  • /etc/cron.daily
  • /etc/cron.hourly
  • /etc/cron.monthly
  • /etc/cron.weekly

の4つがあるらしい。調べてみると全部ある。他にも

  • /etc/cron.d
  • /etc/crontab

がある。せっかくなので nano で中身を見てみる。

crontab 以外は空っぽだった。

crontab

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.d$
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.w$
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.m$
#

じゃあ、使い方はどうするのか?

「crontabの書き方」 (server-memo.net)
http://www.server-memo.net/tips/crontab.html

表示

crontab -l
no crontab for root

なんのこっちゃ。

crontab -e
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.tiny

エディターを選べということか。 nano が一番簡単、とコメントも付いてるな。

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

何かファイルが開かれた。

10分毎にコマンドを実行する書き方

*/10  *  *  *  *  ここにコマンドを書く

みたいなんで、プログラムが起動していなければ起動する、といったプログラムを組みたいが……。

pgrep

まず ps でプロセスを一覧してみる。

ps
  PID TTY          TIME CMD
24330 pts/2    00:00:00 php
24349 pts/2    00:00:00 sudo
24350 pts/2    00:00:00 su
24351 pts/2    00:00:00 bash
25814 pts/2    00:00:00 ps

次に pgrep で、コマンド名を一致検索する。

pgrep -l su
12129 su
24349 sudo
24350 su

これだと PHP を起動すると php になるかもしれない。
bash スクリプトを起動しても bash になるんじゃないか。
プログラム名を調べられないものか。

だったら jobs でいいんじゃないか? コマンド名だけ取れればいいかと思ったが、そういうオプションもないようだ。

jobs -r
[1]+  Running                 nohup /usr/bin/php /home/★user/shogi/php_receive/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &

ここで頭30文字を削り取れば、残りはコマンド名になるんじゃないか?

「cut 文字列を切り出す」 (UNIX入門)
http://www.k4.dion.ne.jp/~mms/unix/linux_com/cut.html

# jobs -r | cut -c31-
nohup /usr/bin/php /home/★user/shogi/php_receive/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &

よし。

この文字列に一致しなかった場合は、コマンドを叩くことにする。
それをシェル・スクリプトで書くなら……。

少しずつ書いていこう。PHPと似ていて全然違うから間違えやすい。

# nano tamesi9.sh

tamesi9.sh

#!/bin/bash
CMD = $(jobs -r | cut -c31-)
echo "(^q^)${CMD}"
# ls -an
略
-rw-r--r-- 1 0 0   61 Mar  8 00:19 tamesi9.sh
# chmod 755 tamesi9.sh
# ls -an
略
-rwxr-xr-x 1 0 0   61 Mar  8 00:19 tamesi9.sh
# ./tamesi9.sh
./tamesi9.sh: line 2: CMD: command not found
(^q^)

うーむ。

「シェルプログラミングの基礎知識」 (Shinta's WEBSITE)
http://www.gadgety.net/shin/tips/unix/shell.html

イコールの両端に スペースを入れてはいけないみたいだ。

tamesi9.sh

#!/bin/bash
CMD=$(jobs -r | cut -c31-)
echo "(^q^)${CMD}"
./tamesi9.sh
(^q^)

エラーは無かったが、期待した結果も無かった。

tamesi9b1.sh

#!/bin/bash
echo $(jobs -r | cut -c31-)

行も出てこなくなった。

tamesi9b2.sh

#!/bin/bash
jobs -r | cut -c31- | echo

これも、行が出てこない。

tamesi9b3.sh

#!/bin/bash
jobs | echo

これも、行が出てこない。こんな書き方無いのか。

「bash シェルスクリプト入門 -シェルスクリプトのいろは-」 (UNIX & Linux コマンド・シェルスクリプト リファレンス」)
http://shellscript.sunone.me/tutorial.html

「シェルの変数に慣れる」 (@IT
http://www.atmarkit.co.jp/ait/articles/0010/19/news003.html

「Linux:出力結果やテキストをファイルに書き出す方法」 (raining)
http://raining.bear-life.com/linux/%E5%87%BA%E5%8A%9B%E7%B5%90%E6%9E%9C%E3%82%84%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%92%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E6%9B%B8%E3%81%8D%E5%87%BA%E3%81%99%E6%96%B9%E6%B3%95

tamesi9b4.sh

#!/bin/bash
ls | cut -c2- > tmp1.txt
# nano tmp1.txt
oop8.sh
amesi9b1.sh
amesi9b2.sh
amesi9b3.sh
amesi9b4.sh
amesi9.sh
mp1.txt

この書き方でいけるのか。

tamesi9b5.sh

#!/bin/bash
jobs -r | cut -c31- > tmp1.txt
# chmod 755 tamesi9b5.sh
# ./tamesi9b5.sh
# nano tmp1.txt

だめ。

tamesi9b5.sh

#!/bin/bash
jobs -r > tmp1.txt
cut -c31- tmp1.txt > tmp1.txt

だめ。

tamesi9b5.sh

#!/bin/bash
jobs -r > tmp1.txt
# cut -c31- tmp1.txt > tmp1.txt

だめ。

jobs -r は出力できないのか?

jobs -r

コマンドラインでは jobs -r が効くが、シェルスクリプトの中に書くと 何も出力しないようだ。
何が違うのか分からない。
jobs > tmp1.txt でもダメで、 echo "abc" > tmp1.txt ならオッケーのようだ。

シェルスクリプトの中では jobs は使えないのか。

タイムスタンプは出力できるか

先に PHP の方で、タイムスタンプを出力するようにしよう。

# nano loop10.php
<?php
// 環境設定
date_default_timezone_set('Asia/Tokyo');

// 設定
$file = 'date.txt';

// 現在時刻をファイルへ書出し
$today = date("Y-m-d H:i:s");
file_put_contents( $file, $today );
# chmod 747 loop10.php
# php loop10.php
# nano date.txt
2017-03-08 01:30:20

日付は出力できた。しかしバッシュでこの日付を読込んだり、日付計算したりできるんだろうか?

シェルスクリプトから PHP を起動できるか?

bash_receive、php_receive といったフォルダー名を、
bash_service、php_service といったフォルダー名に変更する。

# mv bash_receive bash_service
# mv php_receive php_service
# nano kicker_dequeueBroker.sh

kicker_dequeueBroker.sh

#!/bin/bash
nohup /usr/bin/php /home/★user/shogi/php_service/dequeueBroker.php > /home/★user/shogi/php_log/dequeueBroker.out.log 2> /home/★user/shogi/php_log/dequeueBroker.err.log < /dev/null &

これはおいといて、次は PHP の方。

# cp loop6.php dequeueBroker.php

これでよし。次、cron の設定。

crontab -e
55  *  *  *  *  /home/★user/shogi/bash_service/kicker_dequeueBroker.sh

あれ? 直接 PHP 蹴ったらいいんじゃないのか? するとコマンドが長くなるのか。じゃあこれでいいか。

これで 毎回、55分 に実行されるんだろうか?

「crontabファイル変更後の反映」 (U字路)
http://blog.livedoor.jp/u_26/archives/1819139.html

しくみ

これで仮に動くなら、http://★.★.★.★/tamesi5.php にアクセスすると、メッセージキューに文字が格納されて、dequeueBroker.php がそれを取得し、dequeueBroker.out.log に書き出す、といった流れになるはず。

そして ログアウトしても動いているという前提だ。

cron が動かした job を見る方法はあるんだろうか?

よく使うコマンドを、シェル・スクリプトにしておく。

loop6.sh

#!/bin/bash
nohup /usr/bin/php /home/★user/shogi/php_service/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &
# chmod 755 loop6.sh

サーバーの時刻は確認できるんだろうか?

「LinuxのUbuntuで日付や時刻を表示・設定するコマンド」 (MiuxMiu)
http://www.miuxmiu.com/archives/2011/03/19/linux_ubuntu_date_time_view_settings_command.html

date
Wed Mar  8 02:07:39 JST 2017

今、2017-03-08 の 2時7分だから、
サーバー時刻は 2017年のMar月8日の 2時7分39秒 なら合ってるか。

cron 実行されなかったな。

cron が動いているかをどうやって確認するのか?

「cronが動いているかの確認」 (MAKIEDAN MEMO BLOG)
http://makiedan.hatenablog.com/entry/20140404/1396600750

# /etc/rc.d/init.d/crond status
-su: /etc/rc.d/init.d/crond: No such file or directory

rc.d は無くて rc0.d ~ rc6.d ならあるんだが、困ったもんだ。

「crontabの使い方」 (Saba note)
http://saba.omnioo.com/note/1233/crontab%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/

cron -l だと設定ファイルが出てきてしまう。

# /etc/init.d/cron staus
 * Usage: /etc/init.d/cron {start|stop|status|restart|reload|force-reload}

動いてないのかな、これ。

cron を起動させる

# /etc/init.d/cron start
[ ok ] Starting cron (via systemctl): cron.service.

今動いたんだろうか?

もっと簡単に

サーバー時刻を、ファイルに書き込むコマンドは?

date > tmp3

tmp3

Wed Mar  8 02:38:39 JST 2017

サーバー時刻を、ファイルに書き込むシェル・スクリプトは?

tamesi12.sh

#!/bin/bash
date > tmp12
Wed Mar  8 02:52:13 JST 2017

これはオッケーだ。

じゃあ、これを 1 分毎に叩く cron ジョブを設定できるだろうか?

crontab -e
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
0-59/1 * * * * /home/★usr/shogi/php_service/tamesi12.sh

これでどうか?

crontab: installing new crontab

なんか初めて見るレスポンスが出力されていた。さっき /etc/init.d/cron を start させたことと関係あるのだろうか?

cron にはどのパーミッションを与えればいいんだろうか?

実行するファイル

-rwxr-xr-x 1 0 0   26 Mar  8 02:51 tamesi12.sh

書き出し先ファイル

# chmod 666 tmp12

ぜんぜん 更新時刻が 更新される様子がない。

cron が動いているか確認しよう

# cron status
cron: can't lock /var/run/crond.pid, otherpid may be 507: Resource temporarily unavailable

「cron deamon not working」 (phusion/baseimage-docker)
https://github.com/phusion/baseimage-docker/issues/115

# cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

ubuntu の cron は、他の cron と違うんじゃないか?

「crontabが上手く動かない時のヒント」 (クリエイター見習いの落書きノート)
http://creatornote.blog87.fc2.com/blog-entry-24.html

# less /var/log/syslog | grep CRON
~略~
Mar  8 03:26:01 ★略 CRON[30356]: (root) CMD (/home/★user/shogi/php_service/tamesi12.                                                sh)

うん? cron は動いてるんじゃないか、rootユーザーで?

でも ファイル書き込みはできてない。

cron は実行ファイルを叩いていて、それで エラーとかログは無いのか?

「cronが機能していないようです。」 (Ubuntu日本語フォーラム)
https://forums.ubuntulinux.jp/viewtopic.php?id=6926

cronで シェル・スクリプトを動かすときの書き方は、コマンドを書くところの 頭にbash を付けるんだろうか?

0-59/2 * * * * /home/★user/shogi/php_service/tamesi12.sh

これで2分おきに再度チャレンジ。

変化なし。

記事にある「cronのユーザーはroot」という表現は 何を指しているのだろうか?

man cron

man cron

で説明書きが出てきた。

/etc/init.d

/etc/init.d

かどこかに設定ファイルがあるんだろうか?

# ls -an
total 28
drwxr-xr-x   2 0 0  4096 Mar  8 03:25 .
drwxr-xr-x 102 0 0 12288 Mar  8 03:54 ..
-rw-r--r--   1 0 0   670 Mar  2  2016 php
-rw-r--r--   1 0 0   102 Feb  9  2013 .placeholder
-rw-r--r--   1 0 0   190 Mar  4 21:13 popularity-contest

とくに何にもない。

/etc/crontab

/etc/crontab

という設定ファイルがあるのか?

/etc/crontab

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

時、日、月、週 でファイルを分けているのだろうか?

/etc/environment

/etc/environment

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

Windowsで言うところの環境変数でも入ってるんだろうか。実行コマンドへのパスが通してある感じ。

その行の上に、1行書き足してみる。

SHELL=/bin/bash

そのあとは何をリスタートさせたらいいんだろうか?

/etc/init.d/cron status
● cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2017-03-04 21:18:23 JST; 3 days ago
     Docs: man:cron(8)
 Main PID: 507 (cron)
   CGroup: /system.slice/cron.service
           └─507 /usr/sbin/cron -f

Mar 08 03:56:01 tk2-217-18401 CRON[31079]: (root) CMD (bash /home/★user/shogi/php_service/tamesi12.sh)
Mar 08 03:56:01 tk2-217-18401 CRON[31078]: pam_unix(cron:session): session closed for user root
Mar 08 03:58:01 tk2-217-18401 CRON[31116]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 08 03:58:01 tk2-217-18401 CRON[31117]: (root) CMD (bash /home/★user/shogi/php_service/tamesi12.sh)
Mar 08 03:58:01 tk2-217-18401 CRON[31116]: pam_unix(cron:session): session closed for user root
Mar 08 04:00:01 tk2-217-18401 CRON[31155]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 08 04:00:01 tk2-217-18401 CRON[31156]: (root) CMD (bash /home/★user/shogi/php_service/tamesi12.sh)
Mar 08 04:02:01 tk2-217-18401 CRON[31192]: pam_unix(cron:session): session opened for user root by (uid=0)
Mar 08 04:02:01 tk2-217-18401 CRON[31193]: (root) CMD (bash /home/★user/shogi/php_service/tamesi12.sh)
Mar 08 04:02:01 tk2-217-18401 CRON[31192]: pam_unix(cron:session): session closed for user root

おや、ステータスが見れるようになっている。だったら 昨日は動いてなかったんだ。

# /etc/init.d/cron restart
[ ok ] Restarting cron (via systemctl): cron.service.

勝手にリスタートさせた。

cron のログ

/var/log/syslog

らしいんだが。おや? 今見にいくとある。

Mar  7 06:25:01 tk2-217-18401 CRON[5015]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ))

kernel が大量にログを吐いているが、CRON はエラーっぽいのは吐いていない。

どうしたものか。

cron のルート権限

「Ubuntu cron crontab シェルスクリプト 設定」 (コンピュータとかバイクとか。)
http://esoz.blog.fc2.com/blog-entry-40.html

ルート権限で設定するには

sudo crontab -e

とやる必要があるのか。自分のcronの設定だけいじっててもダメか。

sudo crontab -e
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
0-59/2 * * * * bash /home/★user/shogi/php_service/tamesi12.sh

bash を絶対パスにしてみるか?

0-59/2 * * * * /bin/bash /home/★user/shogi/php_service/tamesi12.sh

tail /var/log/syslog

と書くと、ログの最近の数件を取れるようだが、kernel ばっかりだ。

シェルスクリプト実行時のカレントディレクトリが想定と異なる。
 →シェルスクリプトの冒頭付近に「cd /hoge/hoge」を絶対パスで書き込んでカレントディレクトリを設定する。

「コンピュータとかバイクとか。」 (Ubuntu cron crontab シェルスクリプト 設定)
http://esoz.blog.fc2.com/blog-entry-40.html

なんのことだろうか。

とりあえず、シェル・スクリプトには カレントディレクトリも記述しておくといいのか。

なんで PHP用のフォルダーに .sh を入れてるんだ。

移動。

mv tamesi12.sh ../bash_service/tamesi12.sh
mv tmp12 ../bash_service/tmp12

修正

sudo crontab -e
0-59/2 * * * * /bin/bash /home/★user/shogi/bash_service/tamesi12.sh
less /var/log/syslog | grep CRON
略
Mar  8 04:26:01 tk2-217-18401 CRON[31790]: (root) CMD (/bin/bash /home/★user/shogi/php_service/tamesi12.sh)
Mar  8 04:28:01 tk2-217-18401 CRON[31844]: (root) CMD (/bin/bash /home/★user/shogi/php_service/tamesi12.sh)
Mar  8 04:28:01 tk2-217-18401 CRON[31843]: (CRON) info (No MTA installed, discarding output)
Mar  8 04:30:01 tk2-217-18401 CRON[31881]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi12.sh)
Mar  8 04:32:01 tk2-217-18401 CRON[31929]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi12.sh)

フォルダーの移動は反映されたようだが。

シェル・スクリプトのカレント・ディレクトリ

tamesi12.sh

#!/bin/bash
date > tmp12

実行したファイルのある場所をカレント・ディレクトリにしてくれるわけじゃないのか。
じゃあ、追記。

tamesi12.sh

#!/bin/bash
cd /home/★user/shogi/bash_service
date > tmp12
# ls -an
略
-rw-rw-rw- 1 0 0   29 Mar  8 04:38 tmp12

タイムスタンプが更新されている。マジか。

# nano tmp12
Wed Mar  8 04:38:01 JST 2017

bashのシェル・スクリプトにはカレント・ディレクトリも書かないとだめか~(^~^)

じゃあ次は cron を使って nohup かつ バックグラウンドで実行

loop13.sh

#!/bin/bash
cd /home/★user/shogi/bash_service
nohup /usr/bin/php /home/★user/shogi/php_service/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php_log/loop6.err.log < /dev/null &
echo "(^q^)CRON: Start infinity loop!"

あれ、これ毎分実行されたら、無限ループのプロセス大量生産されていやだな……。
1回だけ常駐してくれたらいい。

# sudo crontab -e
3 * * * * /bin/bash /home/★user/shogi/bash_service/tamesi13.sh

これで 3分 になったら

less /var/log/syslog | grep CRON

しよう。

Mar  8 05:03:01 tk2-217-18401 CRON[32719]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi13.sh)

叩いてはくれたんだが、うまく実行されたのかどうか、どうやって確認しよう。 echo は出力されていない。

おや?

/home/★user/shogi/php_log# ls -l
total 8
-rw-rw-rw- 1 root root 588 Mar  8 05:47 loop6.err.log
-rw-rw-rw- 1 root root 407 Mar  8 02:12 loop6.out.log

loop6.err.log に日付の更新がある。

PHP Fatal error:  Uncaught Error: Class 'PhpAmqpLib\Message\AMQPMessage' not found in /home/★user/shogi/php_receive/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Channel/AbstractChannel.php:264
Stack trace:
#0 /home/★user/shogi/php_receive/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Channel/AbstractChannel.php(384): PhpAmqpLib\Channel\AbstractChannel->wait_content()
#1 /home/★user/shogi/php_receive/loop6.php(44): PhpAmqpLib\Channel\AbstractChannel->wait()
#2 {main}
  thrown in /home/★user/shogi/php_receive/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Channel/AbstractChannel.php on line 264

composer.json を調べるか……。

★/home/★user/shogi/php_service# composer install
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Nothing to install or update
Generating autoload files
★/home/★user/shogi/php_service# composer update
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files

更新はできてるっぽい。

あらっ! ディレクトリ・パスをよく見ると php_receive ディレクトリを見にいっているが、 php_service に変えたんだった。なんで変える前のディレクトリを見に行ってるんだろうか?

調べるか……。

cron が実行したバックグラウンド・ジョブを停止させるには?

less /var/log/syslog | grep tamesi13
Mar  8 05:03:01 tk2-217-18401 CRON[32719]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi13.sh)

この 32719 というのはプロセスIDだったりするんだろうか?

「【ps・kill】実行中のプロセス表示と強制終了」 (Qiita)
http://qiita.com/shuntaro_tamura/items/4016868bda604baeac3c

ps aux
略
root     24330  0.0  1.3 232308 14052 pts/2    S    Mar07   0:02 /usr/bin/php /home/★user/shogi/php_receive/loop6.php

怪しいプロセスはいっぱい出てきたが、32719 というプロセス番号は無いようだ。

ps aux | grep receive
root      2560  0.0  0.0  12936   988 pts/2    S+   06:19   0:00 grep --color=auto receive
root     20355  0.0  1.3 232308 14064 ?        S    Mar07   0:03 php /home/★user/shogi/php_receive/loop6.php
root     22501  0.0  0.1  11248  1364 ?        S    Mar07   0:00 /bin/bash /home/★user/shogi/bash_receive/loop8.sh
root     22897  0.0  0.1  11248  1368 ?        S    Mar07   0:00 /bin/bash /home/★user/shogi/bash_receive/loop8.sh
root     23422  0.0  0.1  11248  1368 ?        S    Mar07   0:00 /bin/bash /home/★user/shogi/bash_receive/loop8.sh
root     23910  0.0  1.3 232308 14052 ?        S    Mar07   0:02 /usr/bin/php /home/★user/shogi/php_receive/loop6.php
★user    23978  0.0  1.3 232308 14056 ?        S    Mar07   0:02 /usr/bin/php /home/★user/shogi/php_receive/loop6.php
root     24330  0.0  1.3 232308 14052 pts/2    S    Mar07   0:02 /usr/bin/php /home/★user/shogi/php_receive/loop6.php

全部 S なので、一時停止中だが、落としたらいいんだろうか?

kill 24330
ps aux | grep receive
root      2588  0.0  0.0  12936   988 pts/2    S+   06:20   0:00 grep --color=auto receive
root     20355  0.0  1.3 232308 14064 ?        S    Mar07   0:03 php /home/★user/shogi/php_receive/loop6.php
root     22501  0.0  0.1  11248  1364 ?        S    Mar07   0:00 /bin/bash /home/★user/shogi/bash_receive/loop8.sh
root     22897  0.0  0.1  11248  1368 ?        S    Mar07   0:00 /bin/bash /home/★user/shogi/bash_receive/loop8.sh
root     23422  0.0  0.1  11248  1368 ?        S    Mar07   0:00 /bin/bash /home/★user/shogi/bash_receive/loop8.sh
root     23910  0.0  1.3 232308 14052 ?        S    Mar07   0:02 /usr/bin/php /home/★user/shogi/php_receive/loop6.php
★user    23978  0.0  1.3 232308 14056 ?        S    Mar07   0:02 /usr/bin/php /home/★user/shogi/php_receive/loop6.php

おっ、落とせた。要らないの全部落とそう。

落とした。

次はまた cron で実行しよう。

sudo crontab -e
less /var/log/syslog | grep CRON
Mar  8 06:28:01 tk2-217-18401 CRON[2889]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi13.sh)

よし、実行された。
Cron のスケジュールから外しておく。

ps aux | grep receive

いないな。スケジュールから外すとダメなのか?

ps aux
略
root     28496  0.0  1.3 232308 14068 pts/2    S    02:01   0:01 /usr/bin/php /home/★user/shogi/php_service/dequeueBroker.php

これが一時停止中だが、エラーでも出ているんだろうか?

http://★.★.★.★/tamesi5.php に数回アクセスして エンキュー しておく。
デキュー・ブローカーが稼働していれば、ログに書き出すだろう。

同期してなくていいはずだ。

45分に実行。

less /var/log/syslog | grep CRON
略
Mar  8 06:45:01 tk2-217-18401 CRON[3243]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi13.sh)

/home/★user/shogi/php_log# ls -l
total 8
-rw-rw-rw- 1 root root 588 Mar  8 06:04 loop6.err.log
-rw-rw-rw- 1 root root 407 Mar  8 02:12 loop6.out.log

6:45 にログの更新はない。

ps a
  PID TTY      STAT   TIME COMMAND
  757 ttyS0    Ss+    0:00 /sbin/agetty --keep-baud 115200 38400 9600 ttyS0 vt220
  758 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
 3297 pts/2    R+     0:00 ps a
24156 pts/2    Ss     0:00 -bash
24349 pts/2    S      0:00 sudo su -
24350 pts/2    S      0:00 su -
24351 pts/2    S      0:02 -su
28496 pts/2    S      0:01 /usr/bin/php /home/★user/shogi/php_service/dequeueBroker.php

dequeueBroker.php は停止してるが、エラーログは無いだろうか?

★/home/★user/shogi/bash_service# nano kicker_dequeueBroker.sh
#!/bin/bash
nohup /usr/bin/php /home/★user/shogi/php_service/dequeueBroker.php > /home/★user/shogi/php_log/dequeueBroker.out.log 2> /home/★user/shogi/php_log/dequeueBroker.err.log < /dev/null &

エラーがあれば /home/★user/shogi/php_log/dequeueBroker.err.log に出力されるはずだが。

あれっ!!

★/home/★user/shogi/bash_service# nano kicker_dequeueBroker.sh

kicker_dequeueBroker.sh

nohup /usr/bin/php /home/csg10/shogi/php_service/dequeueBroker.php > /home/csg10/shogi/php_log/dequeueBroker.out.log 2> /home/csg10/shogi/php_log/dequeueBroker.err.log < /dev/null &

カレント・ディレクトリを指定していないじゃないか。

cd /home/★user/shogi/bash_service

これを書き足しておこう。

less /var/log/syslog | grep CRON
略
Mar  8 07:06:01 tk2-217-18401 CRON[3566]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/tamesi13.sh)

動いたようだ。
ログは測れていない。

カレント・ディレクトリは、想定しているディレクトリを指定しないと。

cd /home/★user/shogi/php_service

おやっ! 実行するプログラムを間違えてないか?

'''
29 * * * * /bin/bash /home/★user/shogi/bash_service/tamesi13.sh
'''

じゃなくて、

'''
29 * * * * /bin/bash /home/★user/shogi/bash_service/kicker_dequeueBroker.sh
'''

だろう。なんで見えないんだろう。

less /var/log/syslog | grep CRON
略
Mar  8 07:30:01 tk2-217-18401 CRON[4055]: (root) CMD (/bin/bash /home/★user/shogi/bash_service/kicker_dequeueBroker.sh)
/home/★user/shogi/php_log# ls -l
total 12
-rw-r--r-- 1 root root   0 Mar  8 07:30 dequeueBroker.err.log
-rw-r--r-- 1 root root 358 Mar  8 07:30 dequeueBroker.out.log
-rw-rw-rw- 1 root root 588 Mar  8 06:04 loop6.err.log
-rw-rw-rw- 1 root root 407 Mar  8 02:12 loop6.out.log

ログができている。

中身は初期状態のもの。デキューしている様子はない。

php を直接叩いてみる。そして [Ctrl]+[C] で終了。

How to use
==========

    Start infinity loop
    -------------------
        After ( nohup /usr/bin/php /home/★user/shogi/php_service/loop6.php > /home/★user/shogi/php_log/loop6.out.log 2> /home/★user/shogi/php$
        By absolute path.

    To finish kill
    --------------
        jobs
        kill %(job number)
 [x] Received Flying Dragon!

1行出力されている。

書き直してみる。

dequeueBroker.php

<?php
// デキュー
// Cronで1回キックしろだぜ☆(^~^)

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

// プロセス間通信の前準備をするぜ☆(^~^)
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$QKey = '1111';
$channel->queue_declare($QKey, false, false, false, false);

// キューを開いてしまえば、あとは無限ループ!

// デキューしたタイミングですることをここに書く
$callback = function($msg) {
    echo " [x] Received ", $msg->body, "\n";
};
$channel->basic_consume($QKey, '', false, true, false, false, $callback);

// 無限ループ
while(count($channel->callbacks))
{
    // ここでブロックしながらデキューする
    $channel->wait();
}
// ここに来ない
echo "無限ループを抜けた!?☆(^~^)!?";
// $channel->close();
// $connection->close();

説明の出力を省いて、無限ループを抜けたときに、メッセージを1つログに吐き出すことにした。

root      4945  0.0  1.3 232308 14040 ?        S    08:05   0:00 /usr/bin/php /home/★user/shogi/php_service/dequeueBroker.php

なんでストップしてるんだろ。

プロセスは ストップしていても動いている のでは?

ストップしているプロセスがあり、
ブラウザで http://★.★.★.★/tamesi5.php を叩くと ログファイルに文字が書き込まれているので、
プロセスは止まっているように見えて動いているのか、
それとも テストで叩いた 別のプロセスが動いているのだろうか?

区別ができない。

PHP でデキューせずに、C# でデキューできないのか?

なんで C# でデキューできないんだろう。

csharp_service というフォルダーを掘ろう。

mkdir csharp_service
mkdir csharp_log

この中に試しで作ったプログラムを移すことにする。

mv tamesi1 ape1.sh
mv tamesi2 ape2.sh
mv tamesi3 ape3.sh
mv tamesi4 ape4.sh
mv tamesi5 ape5.sh
mv tamesi6 ape6.sh
mv tamesi7 ape7.sh
mv tamesi8 ape8.sh
mv tamesi9 ape9.cs
mv tamesi9.exe ape9.exe
mv tamesi10 ape10.cs
mv tamesi10.exe ape10.exe

mv MsgQueue_Old.cs ../../csharp_service/MsgQueue_Old.cs
mv MsgQueue.cs ../../csharp_service/MsgQueue.cs
mv MsgQueue.exe ../../csharp_service/MsgQueue.exe

なぜだか分からないが、C# がエンキューした メッセージは C# にしか見れないし、PHP がエンキューしたメッセージもデキューできないようだ。

なんだろう。

PHPの受け取り口を改造しよう

とりあえず役に立ちそうなのは2つ。

tamesi2.php
tamesi5.php

これを統合して、tamesi14.php を作ってみる。

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

// GETクエリ文字列を取得
$QMsg = urldecode($_SERVER['QUERY_STRING']);
if( "" === $QMsg)
{
    $QMsg = "hello, world";
}

// 別のクエリーも送れることを説明
echo '(^q^)' . $QMsg . '<br />';
echo 'これを1回クリックしろだぜ☆m9(^~^)!<br />';
echo '<a href="http://★.★.★.★/tamesi14.php?ClickSitanDaze">http://★.★.★.★/tamesi14.php?ClickSitanDaze</a><br />';

// キューを開く
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$QKey = '1111';
$channel->queue_declare($QKey, false, false, false, false);

// エンキューする
$msgObj = new AMQPMessage( $QMsg );
$channel->basic_publish($msgObj ,'' ,$QKey);

echo "対局プログラムの近くに届けておくぜ☆(^▽^)v ['" . $QMsg . "']\n";

// リソースを開放する
$channel->close();
$connection->close();

ログアウトしても、プロセスは動いているだろうか?

dequeueBroker.out.log に文字列が入るところまではできたが、ログアウトしても プロセスは動いているかどうかが問題だ。

「Ubuntu LinuxにRabbitMQをインストールする」 (CLOVER)
http://d.hatena.ne.jp/Kazuhira/20160531/1464706671

RabbitMQ が落ちてるのかと思ったがログは吐いてるし。

PHP exec

「外部コマンドを実行 - exec()、system()」 (PHP入門)
http://webkaru.net/php/function-exec-system/

コマンドラインのコマンドを PHP から使えるのだろうか?試してみよう。

php_service/tamesi15.php

<?php
// 引数無し
var_dump(
    exec(
        'ls'
    )
);

// 引数有り
var_dump(
    exec(
        'ls', $out, $ret
    )
);
print_r( $out );
var_dump( $ret );
php tamesi15.php
string(6) "vendor"
string(6) "vendor"
Array
(
    [0] => composer.json
    [1] => composer.lock
    [2] => dequeueBroker.php
    [3] => loop10.php
    [4] => loop6.php
    [5] => tamesi15.php
    [6] => vendor
)
int(0)

exec( ) の戻り値は単に $out の最終行だろうか。コマンドの戻り値は $ret に入ったのだろう。

expect コマンド

「Linuxの対話がめんどくさい?そんな時こそ自動化だ!-expect編-」 (Qiita)
http://qiita.com/ine1127/items/cd6bc91174635016db9b

1行で書く形式なのか、暗号みたいだ。

「Expect の使用例」 (PHPマニュアル)
http://php.net/manual/ja/expect.examples-usage.php

こっちは PHPプログラムそのまんまっぽい。

長くなってきたので次の記事へ

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1