我正在尝试找到重新调用Python脚本的最佳方法。目前它的工作方式与http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L285类似。 START_CTX
是在http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L82-86创建的。
代码依赖sys.argv[0]
作为“来电者”。但是,如果使用以下方法调用它,则会失败:
python script.py ...
这种情况确实有效:
python ./script.py ...
因为代码在运行os.chdir
之前使用os.execlp
。
我注意到os.environ["_"]
,但我不确定那会有多可靠。另一种可能的情况是检查sys.argv[0]
上是否PATH
并且不可执行,并在致电sys.executable
时使用os.execlp
。
有关更好地解决此问题的方法的想法吗?
答案 0 :(得分:1)
我认为真正的问题是gunicorn / arbiter.py代码希望每次都使用完全相同的环境来执行Python脚本。这很重要,因为调用的Python脚本是未知的,每次都以相同的方式称为完全非常重要。
我的感觉是你遇到的问题与仲裁者在Python脚本的调用之间发生了变化的环境有关。
在http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L85-89中,我们看到仲裁器将python可执行文件和args存储到self.START_CTX中。
然后在http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L303-305中,我们看到execvpe是用sys.executable,修改过的args和os.environ调用的。
如果os.environ在其他地方发生了变化(即PWD变量),则无法正确调用您的可执行文件(因为您不再位于正确的文件夹中)。仲裁者似乎通过将cwd存储在START_CTX中来处理这种可能性。所以问题仍然存在,为什么调用失败了?
我尝试了一些测试代码,我写了如下:
#!/usr/bin/env python
import sys
import os
def main():
"""Execute twice"""
cwd = os.getcwd()
print cwd
print sys.argv
if os.path.exists("/tmp/started.txt"):
os.unlink("/tmp/started.txt")
print "Deleted /tmp/started.txt"
print
return
args = [sys.executable] + sys.argv[:]
os.system("touch /tmp/started.txt")
print "Created /tmp/started.txt"
print
os.execvpe(sys.executable, args, os.environ)
if __name__ == '__main__':
main()
当我从命令行执行此代码时,它可以正常工作:
guest@desktop:~/Python/Test$ python selfreferential.py
/Users/guest/Python/Test
['selfreferential.py']
Created /tmp/started.txt
/Users/guest/Python/Test
['selfreferential.py']
Deleted /tmp/started.txt
guest@desktop:~/Python/Test$ python ./selfreferential.py
/Users/guest/Python/Test
['./selfreferential.py']
Created /tmp/started.txt
/Users/guest/Python/Test
['./selfreferential.py']
Deleted /tmp/started.txt
guest@desktop:~/Python/Test$ cd
guest@desktop:~$ python Python/Test/selfreferential.py
/Users/guest
['Python/Test/selfreferential.py']
Created /tmp/started.txt
/Users/guest
['Python/Test/selfreferential.py']
Deleted /tmp/started.txt
guest@desktop:~$ python /Users/guest/Python/Test/selfreferential.py
/Users/guest
['/Users/guest/Python/Test/selfreferential.py']
Created /tmp/started.txt
/Users/guest
['/Users/guest/Python/Test/selfreferential.py']
Deleted /tmp/started.txt
guest@desktop:~$
正如你所看到的,做枪炮的事情没有问题。所以,也许你的问题与环境变量有关。或者可能与操作系统执行事物的方式有关。
答案 1 :(得分:0)
我建议采用不同的方法。将所有脚本功能包含在一个函数中,该函数在执行脚本时被调用,该函数可以递归调用自身,而不是执行新进程。