前回の記事 : 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プログラムそのまんまっぽい。