Redhat 6サーバー上のcronで30分ごとに実行することを目的としたシェルスクリプトで、思わぬ障害が発生しました。シェルスクリプトは、基本的にpythonスクリプトを実行するためのコマンドです。
サーバー上のネイティブバージョンpythonは2.6.6ですが、この特定のスクリプトに必要なpythonバージョンはpython 2.7 +。「scl」コマンドを使用することにより、コマンドラインでこれを簡単に実行できます(この例には、python -Vコマンドが含まれており、バージョンの変更を表示しています):
$ python -V
Python 2.6.6
$ scl enable python27 bash
$ python -V
Python 2.7.3
この時点で、python 2.7.3スクリプトをコマンドラインで実行しても問題ありません。
これが問題です。
scl enable python27 bash
コマンドを発行すると、新しいbashシェルセッションが開始され、対話型のコマンドラインでの作業に適しています(これも)。ただし、これをシェルスクリプト内で実行すると、bashコマンドを実行するとすぐに、新しいセッションのためにスクリプトが終了します。
失敗しているシェルスクリプトは次のとおりです。
#!/bin/bash
cd /var/www/python/scripts/
scl enable python27 bash
python runAllUpserts.py >/dev/null 2>&1
「bash」がスクリプトからポップし、新しいbashシェルに入れるため、行4に到達するとすぐに停止します。したがって、実際のpythonコマンドを実行するために必要なコマンドは表示されません。
さらに、30分ごとに実行すると、毎回新しいbashが追加され、これもまた別の問題です。
いくつかの理由により、サーバーのネイティブpythonバージョンを2.7.3に更新することに今は抵抗があります。Redhatyumリポジトリにはまだpython = 2.7.3および手動インストールは、yum更新システムの外にあります。私が理解していることから、yum自体はpython 2.6.x.
ここで、sclを使用する方法を見つけました
SCL環境の1つのヒアドキュメントですべてを行うことが、IMOの最良のオプションです。
scl enable python27 - << \EOF
cd /var/www/python/scripts/
python runAllUpserts.py >/dev/null 2>&1
EOF
別の方法は、scl環境で直接2番目のコマンド(Pythonを使用する唯一のコマンド)を実行することです。
cd /var/www/python/scripts/
scl enable python27 "python runAllUpserts.py >/dev/null 2>&1"
scl enable python27 bash
は、python仮想環境をアクティブにします。
これは、/opt/rh/python27/enable
にあるSCLパッケージの仮想環境の有効化スクリプトをソースするだけで、bashスクリプト内から実行できます。
例:
#!/bin/bash
cd /var/www/python/scripts/
source /opt/rh/python27/enable
python runAllUpserts.py >/dev/null 2>&1
pythonスクリプトを直接実行するのが最も簡単ではありませんか?test_python.py
:
#!/usr/bin/env python
import sys
f = open('/tmp/pytest.log','w+')
f.write(sys.version)
f.write('\n')
f.close()
次に、crontabで:
2 * * * * scl python27 enable $HOME/test_python.py
test_python.py
実行可能ファイル。
別の方法は、Pythonを呼び出すシェルスクリプトを呼び出すことです。 test_python.sh
:
#/bin/bash
python test_python.py
あなたのcrontabで:
2 * * * * scl python27 enable $HOME/test_python.sh
一発ギャグ
scl enable python27 'python runAllUpserts.py >/dev/null 2>&1'
CentOS 6.xのdevtoolsetsでも使用します
me@my_Host:~/tmp# scl enable devtoolset-1.1 'gcc --version'
gcc (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
私はこれまでにscl
のものを一度しか見たことがなく、それがインストールされているシステムにアクセスする準備ができていません。しかし、virtualenv
での方法と漠然と似た方法で、PATHと他のいくつかの環境変数を設定しているだけだと思います。
おそらく、bash
サブプロセス呼び出しpython
を持つようにスクリプトを変更すると、うまくいきます。
#!/bin/bash
cd /var/www/python/scripts/
(scl enable python27 bash -c "python runAllUpserts.py") >/dev/null 2>&1
サブプロセスpython
のシェルにあるbash
のインスタンスは2.7.xのコピーである必要があり、scl
によって行われた他のすべての環境設定はそれによって継承されます。