如何在自身内重新调用python脚本

时间:2010-05-17 02:59:00

标签: python

我正在尝试找到重新调用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

有关更好地解决此问题的方法的想法吗?

2 个答案:

答案 0 :(得分:1)

我认为真正的问题是gunicorn / arbiter.py代码希望每次都使用完全相同的环境来执行Python脚本。这很重要,因为调用的Python脚本是未知的,每次都以相同的方式称为完全非常重要。

我的感觉是你遇到的问题与仲裁者在Python脚本的调用之间发生了变化的环境有关。

  1. http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L85-89中,我们看到仲裁器将python可执行文件和args存储到self.START_CTX中。

  2. 然后在http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L303-305中,我们看到execvpe是用sys.executable,修改过的args和os.environ调用的。

  3. 如果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)

我建议采用不同的方法。将所有脚本功能包含在一个函数中,该函数在执行脚本时被调用,该函数可以递归调用自身,而不是执行新进程。