adsperpage

世界で使われるオフィス互換ソフトウェア(無償)

2017年8月7日月曜日

【Linux CentOS 6.9 64bit】Pythonで簡易的WEBアプリを動作、GETでアクセスしLinuxスクリプトを重複動作をしないように考慮して実行させる。【Python 3.5】

以下の動作環境には、Python3が必要である。
CentOS6.9には、Python3が入っていないので、別途インストールする必要があった。

☆Python3.5をyumで導入する手順

http://akira-arets.blogspot.jp/2017/06/linux-centos68-install-python35-yum.html



■リモートから呼び出したいスクリプトを作成した。

★スクリプトは、重複動作をさけるために、判定ルーティンを設けた。

$ pwd
/home/test/PYTHON3
$ cat testscript.sh
#!/bin/sh

LOGFILE=/home/test/PYTHON3/log

#ここから、重複起動の判定ルーチン

# コマンドラインで指定したパス名 $0 を検索キーにして、既に動作中のプロセスを検索し、最も古いプロセスのIDを取得する。
psnum=`pgrep -fo "$0"`

echo `date` >> $LOGFILE
echo "The Current Script PID is $$" >> $LOGFILE
echo "The COMMAND LINE driven by is $0" >> $LOGFILE
echo "The Firstest PID driven by same COMMAND LINE is $psnum" >> $LOGFILE

# 取得した最古のプロセスIDと、自身のプロセスIDとを比較する。
# 一致しなければ、同一パス名 $0 で呼び出されたプロセスが他に既に存在しているため、二重起動を防止し中断する。

if [ "$$" != "$psnum"  ] ; then
        echo "STOP!  Already This Script working as PID $psnum. and exit." >> $LOGFILE     # 既に同じパスで指定されるスクリプトは起動中である。(二重起動防止のた め中断)
        exit 1
fi

echo "OK!  Starting This Script as PID $$."  >> $LOGFILE             #同じパスで指定されるスクリプトは起動していない。(さらに処理を継続)

#ここまで判定ルーチン


#以下はメインの処理

sleep 70s


■上記スクリプトを呼び出すためのWEBアプリを作成した。

$ pwd
/home/test/PYTHON3
$ cat webtest-v1.0.py
#!/usr/bin/env python3.5
from http.server import HTTPServer, SimpleHTTPRequestHandler
import subprocess

class testHTTPRequestHandler(SimpleHTTPRequestHandler):

        def do_GET(self):

                body = '<!DOCTYPE html><html><body>welcome</body></html>'

                if self.path == '/test/':
                        body = '<html><body>test test test</body></html>'

                        subprocess.call(['/home/test/PYTHON3/testscript.sh &'], shell=True)

                body = body.encode('utf8')

                self.send_response(200)
                self.send_header('Content-type','text/html; charset=utf-8')
                self.send_header('Content-length',len(body))
                self.end_headers()

                self.wfile.write(body)


if __name__ == '__main__':
        #httpd = HTTPServer(('localhost',8000),testHTTPRequestHandler)
        httpd = HTTPServer(('',8000),testHTTPRequestHandler)
        print('Serving HTTP')
        httpd.serve_forever()


■動作テスト

○WEBアプリの起動

$ ./webtest-v1.0.py
Serving HTTP


○初期状態の確認

$ pgrep -fo /home/test/PYTHON3/testscript.sh

$ cat log
cat: log: No such file or directory



<テスト 1>

○ブラウザから、http://ipアドレス:8000/test/ を呼び出し
192.168.250.41 - - [07/Aug/2017 04:03:08] "GET /test/ HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:03:08] "GET /favicon.ico HTTP/1.1" 200 -
○ログを確認

$ cat log
Mon Aug 7 04:03:08 JST 2017
The Current Script PID is 18929
The COMMAND LINE driven by is /home/test/PYTHON3/testscript.sh
The Firstest PID driven by same COMMAND LINE is 18929
OK!  Starting This Script as PID 18929.
$ pgrep -fo /home/test/PYTHON3/testscript.sh
18929


初期状態では、まだスクリプトは動作していないので、処理を継続できた。



<テスト 2>

○以上に続けて、直ぐに、ブラウザから、http://ipアドレス:8000/test/ を呼び出し
192.168.250.41 - - [07/Aug/2017 04:03:48] "GET /test/ HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:03:48] "GET /favicon.ico HTTP/1.1" 200 -
○ログを確認

$ cat log
Mon Aug 7 04:03:08 JST 2017
The Current Script PID is 18929
The COMMAND LINE driven by is /home/test/PYTHON3/testscript.sh
The Firstest PID driven by same COMMAND LINE is 18929
OK!  Starting This Script as PID 18929.
Mon Aug 7 04:03:48 JST 2017
The Current Script PID is 18937
The COMMAND LINE driven by is /home/test/PYTHON3/testscript.sh
The Firstest PID driven by same COMMAND LINE is 18929
STOP!  Already This Script working as PID 18929. and exit.
$ pgrep -fo /home/test/PYTHON3/testscript.sh
18929


既に、スクリプトが実行中だったので、スクリプトの実行は中断された 。



<テスト 3>

○70秒以上経過後に、スクリプトが動作していないことを確認

$ pgrep -fo /home/test/PYTHON3/testscript.sh



○ブラウザから、http://ipアドレス:8000/test/ を呼び出し
192.168.250.41 - - [07/Aug/2017 04:05:12] "GET /test/ HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:05:12] "GET /favicon.ico HTTP/1.1" 200 -

○ログを確認

$ cat log
Mon Aug 7 04:03:08 JST 2017
The Current Script PID is 18929
The COMMAND LINE driven by is /home/test/PYTHON3/testscript.sh
The Firstest PID driven by same COMMAND LINE is 18929
OK!  Starting This Script as PID 18929.
Mon Aug 7 04:03:48 JST 2017
The Current Script PID is 18937
The COMMAND LINE driven by is /home/test/PYTHON3/testscript.sh
The Firstest PID driven by same COMMAND LINE is 18929
STOP!  Already This Script working as PID 18929. and exit.
Mon Aug 7 04:05:12 JST 2017
The Current Script PID is 18945
The COMMAND LINE driven by is /home/test/PYTHON3/testscript.sh
The Firstest PID driven by same COMMAND LINE is 18945
OK!  Starting This Script as PID 18945.


$ pgrep -fo /home/test/PYTHON3/testscript.sh
18945


スクリプトが起動していない状態に復帰していたので、スクリプトの処理を継続できだ。

以上で、テスト完了



■WEBアプリを終了した。

CTRL + c で終了

$ ./webtest-v1.0.py
Serving HTTP
192.168.250.41 - - [07/Aug/2017 04:03:08] "GET /test/ HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:03:08] "GET /favicon.ico HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:03:48] "GET /test/ HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:03:48] "GET /favicon.ico HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:05:12] "GET /test/ HTTP/1.1" 200 -
192.168.250.41 - - [07/Aug/2017 04:05:12] "GET /favicon.ico HTTP/1.1" 200 -
^CTraceback (most recent call last):
  File "./webtest-v1.0.py", line 30, in <module>
    httpd.serve_forever()
  File "/usr/lib64/python3.5/socketserver.py", line 232, in serve_forever
    ready = selector.select(poll_interval)
  File "/usr/lib64/python3.5/selectors.py", line 376, in select
    fd_event_list = self._poll.poll(timeout)
KeyboardInterrupt



<参考>
・subprocess – プロセスを生成して連携する
< http://ja.pymotw.com/2/subprocess/ > 2017年8月6日

・python上でunixコマンドを実行する
< http://qiita.com/tdrk/items/9b23ad6a58ac4032bb3b > 2017年8月6日

・同じパスで指定されるスクリプトが同時に実行されないようにする方法について
< http://akira-arets.blogspot.jp/2017/06/linux-check-whether-running.html > 2017年8月6日