как повторно вызвать скрипт Python внутри себя - PullRequest
3 голосов
/ 17 мая 2010

Я пытаюсь найти лучший способ повторного вызова скрипта 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 ]

1 голос
/ 22 мая 2010

Я думаю, что реальная проблема заключается в том, что код gunicorn / арбитр.py хочет каждый раз выполнять скрипт Python в одной и той же среде. Это важно, потому что вызываемый скрипт Python неизвестен, и важно, чтобы он каждый раз назывался точно одинаково.

Мне кажется, что проблема, с которой вы сталкиваетесь, связана с тем, что среда изменилась между вызовами скрипта Python арбитром.

  1. В http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L85-89, мы видим, что исполняемый файл python и аргументы сохраняются арбитром в self.START_CTX.

  2. Затем в http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L303-305, мы видим, что execvpe вызывается с sys.executable, измененными аргументами и затем 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:~$ 

Как вы видите, не было проблем с тем, что делал Gunicorn. Так что, возможно, ваша проблема связана с переменной окружения. Или, может быть, это как-то связано с тем, как ваша операционная система выполняет вещи.

0 голосов
/ 17 мая 2010

Я бы предложил другой подход. Оберните все функции скрипта в одну функцию, которая вызывается при выполнении скрипта, которая может рекурсивно вызывать себя вместо выполнения нового процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...