2010-05-17 6 views
3

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

Код полагается на sys.argv[0] в качестве «вызывающего». Тем не менее, это не поможет в тех случаях, когда это вызывается с:

python script.py ... 

Этот случай действительно работает:

python ./script.py ... 

, поскольку код использует os.chdir перед запуском os.execlp.

Я заметил os.environ["_"], но я не уверен, насколько это будет надежным. Другим возможным случаем является проверка того, нет ли sys.argv[0] на PATH и не является исполняемым и использовать sys.executable при вызове os.execlp.

Любые мысли о лучшем подходе к решению этой проблемы?

+0

Можно ли просто не разрешить первый случай, или обернуть скрипт в сценарий оболочки, который исправит его? – mikerobi

ответ

0

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

+0

Существует множество способов, с помощью которых можно вызвать Gunicorn, что означает, что он не может заставить все последовательности загрузки в одну точку затвора. –

1

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

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

  1. В http://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L85-89, мы видим, что питон исполняемый и арг хранятся арбитром в 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() 

Когда я выполняю этот код из командной строки, она работает просто отлично:

[email protected]:~/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 

[email protected]:~/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 

[email protected]:~/Python/Test$ cd 
[email protected]:~$ 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 

[email protected]:~$ 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 

[email protected]:~$ 

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

Смежные вопросы