- 締切済み
Python codeのcron実行
QPKGでPythonをダウンロードした後、 http://stackoverflow.com/questions/4460262/running-a-python-script-with-cron を参考に、 (1)Python codeの先頭に[!/usr/bin/env python]を付け (2)chmod +xで実行可能にし、 (3)crontab -e にて1分毎に実行させるようにした のですが1分毎にファイルが作成されません。pythonのコードの保存場所でも間違っているのでしょうか? ※以下にあるpathのQNAPDriveはQnap NASで作成した仮想ドライブ(M:\)です。 (1)コード名[P20_time.py]。実行させると、ファイル名と保存内容が[2014-04-14T11-25-39]のようになり、M driveに保存されるプログラム。EclipseのPydevにて動作確認済み。 #!/usr/bin/env python import datetime D = datetime.datetime.today().strftime("%Y-%m-%dT%H-%M-%S") File_Path = "M:\\" + str(D) + '.txt' F = open(File_Path, 'w') F.write(str(D)) F.close() (2)chmod +xで実行可能にした後、ls -laでパーミッションを確認 -rwxrwxrwx 1 admin administ 209 Apr 13 14:25 P20_time.py* (3)[crontab -e]で編集後、[crontab -l]で表示した内容 01 * * * * /share/QNAPDrive/P20_time.py 作業環境:QNAP NAS TS-212、Windows 7 ―――――――――――――――――――――――――――――――― なお、QNAPのサポートセンターに上記のような質問をした所、 I tried to run your script commands manually in Python command line. But first line will fail: >>> import datetime Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named datetime Maybe you need to install the Python module for your script to work. とあり、プログラム自身がおかしいと指摘されました。ただ、Tera Termを使ってcommand lineで import datetime と入力しても問題なかったです。もうはっきし言ってお手上げです。どなたか御教授頂けるよう、よろしくおねがいします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- kmee
- ベストアンサー率55% (1857/3366)
「pythonの実行ファイル」というのは、Windows流に言えば「python.exe」です。 Linuxでは.exeは不要なので、 python というファイルになります。 PATHからpythonを探す、というのは PATH=/A:/B/B1:/C/C1/C2 のようになっていたら /A/python が存在するか?→ /A/python を実行 ↓存在しないなら /B/B1/python が存在するか?→ /B/B1/python を実行 ↓存在しないなら /C/C1/C2/python が存在するか?→ /C/C1/C2/python を実行 ↓存在しないなら command not found と動作する、ということです。 # このようなとき、実行ファイルEXEをPATHを使って検索できる状態になっていることを # 「EXEにPATHが通っている」と言います。 TeraTermからログインしたときには PATH=/usr/local/bin:/usr/bin cronでは PATH=/usr/bin となっている場合、pythonが /usr/local/bin/python にあったら TeraTermから→ /usr/local/bin/python cronから→ pythonがみつからない となりますし、 /usr/local/bin/python とは別に /usr/bin/python が存在すれば TeraTermから→ /usr/local/bin/python cronから→ /usr/bin/python と別のPythonを実行することになり、インストールされているモジュールが違って importに失敗する、という可能性があります。 PYTHONHOME等の環境変数が定義されていると、モジュールの探し方等が変化します。 http://docs.python.jp/3.3/using/cmdline.html#environment-variables TeraTermからログイン→定義されている cron→定義されていない となっていると、importに失敗する可能性があります。 以上のように、設定が違うと動作が変わります。 TeraTermからのログインで動作しても、cronからは動作しない、ということがありえます。 ですので、そのようなことが起っていないかを確認するのが1点です。 なお、先頭の #! はshebangと呼ばれるもので、「スクリプト」というファイルに #!コマンド と書いてあると コマンド スクリプト と実行したのと(ほぼ)同じになります。P20_time.py というファイルに #!/usr/bin/env python なら /usr/bin/env python P20_time.py です。/usr/bin/env コマンドに python P20_time.pyと引数を付けて実行します。 envコマンドが「(環境変数を設定して)引数で与えられたコマンドを実行する」というコマンドなので、 「python P20_time.py」を実行します。 このときの「python」の探し方は上のPATHを使ったものです。 #!/usr/bin python では「/usr/binコマンドを実行」→「/usr/binはディレクトリなので実行できない」となります > -sh: /share/QNAPDrive/P20_time.py: /usr/bin: bad interpreter: Permission denied これは ・/share/QNAPDrive/P20_time.pyに問題がある ・/usr/bin が 「bad interpreter: Permission denied→インタプリタとして不良: 実行許可されていない」 というエラーです cronが動作するのはNAS の中のLinux上です。 Windows側でどんなドライブになっているかは、まったく関係ありません。 ディレクトリを指定するには、Linux側でどうなっているか、と指定する必要があります。 M:\ も \\192.168.1.7\share\QNAPDrive\ もWindowsでのもので、Linuxのものではありません。 Linuxでは、パスの区切りは / です。 : も \ も「ファイル名の一部」でしかありません。 シェルのコマンドラインでは、\は特殊な意味を持つ文字です。 rm M:\2014-04-15T15-10-58.txt では、「\の後に2」→「2」と変換されてしまい rm M:2014-04-15T15-10-58.txt と同じになり、 M:2014-04-15T15-10-58.txt というファイルは存在しないのでエラーになります。 \をそのまま「\という文字」として認識させる必要があります。 例えば、' でくくるとか rm 'M:\2014-04-15T15-10-58.txt' \\ と2つ続けて書くとか rm M:\\2014-04-15T15-10-58.txt 自分のやりたいことがそのまま載ってることは、まずありません。 Linuxの基礎とPythonの基礎を学んで、それを応用させましょう
- kmee
- ベストアンサー率55% (1857/3366)
cronでうまく動かない、というときは、環境変数をまず疑いましょう。 ・PATHが最低限のものしかありません。TeraTermからの実行時とPATHに違いはないですか? pythonの自体の実行ファイルは同じ場所のものですか? /usr/local/bin/python で、cronでの実行時には/usr/local/binにPATHが通っていない、とかは無いですか? ( /usr/bin/env python と書いた場合、PATHからpythonを探します ) ・PYTHONHOME,PYTHONPATH等の環境変数はcronでの実行時は定義されていません。 必要なモジュールがこれらを定義しないと読み出せなかったりしませんか? ・「import datetimeと入力しても問題なかった」とはありますが、スクリプト全体はどうなのですか? TeraTermから /share/QNAPDrive/P20_time.py と入力したら、期待通りに実行されていますか? ・F = open(File_Path, 'w') が失敗したときの処理がありません。 File_Path = "M:\\" + str(D) + '.txt' にNASのOSからはアクセスできない、ということはないですか? Windowsでのパスではなく、NASのOSから見たときの表記である必要があると思われますが。
補足
kmee様 早速のご回答有難うございます。 (1)「PATHが最低限のものしかありません。~~」の中で、「pythonの自体の実行ファイル」とはP20_time.pyのことでしょうか? それともインタプリタのことでしょうか? イマイチ自分はこのPathの意味がよく分かっておりません。「/usr/bin/env python と書いた場合、PATHからpythonを探します」とあるので、[/usr/bin/env]の中を探したのですがpythonが無かったので、[/usr/bin]をリスト表示で見てみたところ、 ―――――――――――――――――――――――――――― python@ python-config@ python2.7@ python2.7-config@ ―――――――――――――――――――――――――――― のようにありました。そこでP20_time.pyの先頭を[#!/usr/bin python]にして.pyファイルを上書き保存し、Tera Termから実行させたのですが、 ―――――――――――――――――――――――――――― [/] # /share/QNAPDrive/P20_time.py -sh: /share/QNAPDrive/P20_time.py: /usr/bin: bad interpreter: Permission denied ―――――――――――――――――――――――――――― のように出て、実行できませんでした。 (2)「TeraTermから /share/QNAPDrive/P20_time.py と入力したら、期待通りに実行されていますか?」ですが、上記の通り、実行できませんでした。また、Tera TermからP20_time.pyの[import datetime]からコマンド入力したのですが、 ―――――――――――――――――――――――――――― [/] # python Python 2.7 (r27:82500, Aug 21 2010, 10:10:43) [GCC 4.2.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>import datetime ・・・ ―――――――――――――――――――――――――――― 実行はできて.txtファイルは生成されたのですが、[cd / ls]で見てみると、何故かルート直下に [M:\2014-04-15T15-10-58.txt] のように.txtファイルが作成され、それも [rm M:\2014-04-15T15-10-58.txt] とファイルを削除しようとしても [rm: cannot remove `M:2014-04-15T15-10-58.txt': No such file or directory] と出て、ファイルを消せません。 (4)「F = open(File_Path, 'w') が失敗したときの処理がありません。~~」のことですが、今回はちゃんと実行できるのかどうか手っ取り早く確かめるために、失敗した時の処理を含ませておりませんでした。また、Windowsフォルダで仮想ドライブは[QNAPDrive (\\192.168.1.7) (M:)]と表示されているので、P20_time.pyのFile_Pathを [File_Path = "\\192.168.1.7\\share\\QNAPDrive\\" + str(D) + '.txt'] のようにして、Tera Termからコマンド入力したのですが、これもやはりルート直下に[\192.168.1.7\share\QNAPDrive\2014-04-16T11-55-11.txt]のように作成されてしまいました。 私の目的は、Windowsから簡単にファイルなどを置ける仮想ドライブであるM driveに.pyプログラムを置いて実行させ、.txtや.csvなどの出力ファイルを同じdriveの中に生成することです。初めは単純に思っていましたが、本やネットを探し回っても中々適したチュートリアルが見つかりませんでした。上記の問題の対処法以外にも、こういうのが参考になるのではというものがありましたら、ご回答頂ければ幸いです。
お礼
kmee様 返答遅くなり申し訳ありません。結果から言いますと、.pyで保存する際の改行コードが問題でした。 kmee様の回答でも解決出来ず、最終的にQNAPと問い合わせを往復した所、やっと原因が判明しました。 Windowsではコード保存時の改行がバイトコードで[0D0A]なのに対し、Linuxが[0A]でないと認識しないというものでした。 sakura editorで保存時の改行コードを[LF(UNIX)]にした所、[/share/QNAPDrive/P20_time.py]の実行、そして[Crontab -e]にて登録し、1分毎の実行も出来るようになりました。 また、[rm 'M:\2014-04-15T15-10-58.txt']と入力してファイルの削除、出力ファイル先を[File_Path = '/share/QNAPDrive/' + str(D) + '.txt']として[/share/QNAPDrive]のディレクトリにファイルの保存をすることも出来ました。 kmee様が指摘したPathに関する説明で、今まであやふやだったPATHを通すという意味がよく分かり、大変勉強になりました。 貴重なお時間を私の質問に割いて頂き、本当に有難う御座いました。