我遇到了一个shell脚本,它打算在Redhat 6服务器上每隔30分钟在cron中运行一次。 shell脚本基本上只是一个运行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 shell会话,该会话(再次)适用于交互式命令行工作。但是当在shell脚本中执行此操作时,只要它运行bash命令,脚本就会因新会话而退出。
这是失败的shell脚本:
#!/bin/bash
cd /var/www/python/scripts/
scl enable python27 bash
python runAllUpserts.py >/dev/null 2>&1
它只是在它到达第4行时就会停止,因为“bash”将它从脚本中弹出并进入一个新的bash shell。所以它永远不会看到我需要它运行的实际python命令。
另外,如果每30分钟运行一次,每次都会添加一个新的bash,这是另一个问题。
由于多种原因,我不愿意立即将服务器上的本机python版本更新为2.7.3。 Redhat yum repos还没有python 2.7.3,手动安装将在yum更新系统之外。根据我的理解,yum本身运行在python 2.6.x上。
这是我找到使用scl的方法
答案 0 :(得分:25)
在SCL环境中的一个heredoc中做所有事情是最好的选择,IMO:
scl enable python27 - << \EOF
cd /var/www/python/scripts/
python runAllUpserts.py >/dev/null 2>&1
EOF
另一种方法是直接在scl环境中运行第二个命令(这是唯一一个使用Python的命令):
cd /var/www/python/scripts/
scl enable python27 "python runAllUpserts.py >/dev/null 2>&1"
答案 1 :(得分:14)
scl enable python27 bash
激活python虚拟环境。
您可以在bash脚本中执行此操作,只需获取位于/opt/rh/python27/enable
的SCL包的虚拟环境的启用脚本
示例:
#!/bin/bash
cd /var/www/python/scripts/
source /opt/rh/python27/enable
python runAllUpserts.py >/dev/null 2>&1
答案 2 :(得分:7)
直接使用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的shell脚本。 test_python.sh
:
#/bin/bash
python test_python.py
在你的crontab中:
2 * * * * scl python27 enable $HOME/test_python.sh
答案 3 :(得分:3)
一个班轮
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.
答案 4 :(得分:1)
scl
是最愚蠢的“让我们尝试将您锁定在一段时间以来我胡说八道的东西。
这就是我的方法,因此我可以将参数传递给一系列都链接到单个框架文件的脚本:
$ cat /usr/bin/skeleton
#!/bin/sh
tmp="$( mktemp )"
me="$( basename $0 )"
echo 'scl enable python27 - << \EOF' >> "${tmp}"
echo "python '/opt/rh/python27/root/usr/bin/${me}' $@" >> "${tmp}"
echo "EOF" >> "${tmp}"
sh "${tmp}"
rm "${tmp}"
因此,如果存在要运行的脚本,例如/opt/rh/python27/root/usr/bin/pepper
,则可以执行以下操作:
# cd /usr/bin
# ln -s skeleton pepper
# pepper foo bar
它应该可以正常工作。
答案 5 :(得分:0)
我之前只看过这个scl
内容,并且无法随时访问安装了它的系统。但我认为它只是以某种方式设置PATH和其他一些环境变量,这些变量与他们在virtualenv
下的表现方式有些相似。
也许更改脚本以使bash
子进程调用python
起作用:
#!/bin/bash
cd /var/www/python/scripts/
(scl enable python27 bash -c "python runAllUpserts.py") >/dev/null 2>&1
在子流程python
的shell上找到的bash
的实例应该是您的2.7.x副本...... scl
完成的所有其他环境设置应该是由此继承。