29

我遇到了一个 shell 脚本的问题,该脚本打算在 Redhat 6 服务器上的 cron 中每 30 分钟运行一次。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 的方法的地方

http://developerblog.redhat.com/2013/02/14/setting-up-django-and-python-2-7-on-red-hat-enterprise-6-the-easy-way/

4

6 回答 6

29

在 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"
于 2013-07-02T09:07:07.877 回答
23

scl enable python27 bash activates a python virtual environment.

You can do this from within a bash script by simply sourcing the enable script of the virtual environment, of the SCL package, which is located at /opt/rh/python27/enable

Example:

#!/bin/bash
cd /var/www/python/scripts/
source /opt/rh/python27/enable
python runAllUpserts.py >/dev/null 2>&1
于 2015-05-21T06:10:16.040 回答
8

直接使用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
于 2013-10-26T18:47:45.893 回答
6

一个班轮

scl enable python27 'python runAllUpserts.py >/dev/null 2>&1'

我也将它与 CentOS 6.x 上的开发工具集一起使用

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.
于 2015-05-21T09:16:51.843 回答
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

它应该按预期工作。

于 2020-04-20T19:24:44.480 回答
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在 subprocess 的外壳上找到的实例bash应该是您的 2.7.x 副本......并且所有其他环境设置都scl应该被继承。

于 2015-03-09T21:46:48.750 回答