Python: os.execl () - что именно он делает?Почему я получаю эту ошибку? - PullRequest
2 голосов
/ 26 октября 2010

У меня проблемы с развертыванием Django в модуле passenger_wsgi с помощью virtualenv.Код Python в файле passenger_wsgi.py, который должен решить мою проблему:

import os, sys
INTERP = '/home/login/.virtualenvs/env_name/bin/python'
if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)

Первые три строки, которые я понимаю, но у меня есть только очень смутное представление о четвертой, и это та, котораяслучается, дает мне ошибку:

/home/login/.virtualenvs/env_name/bin/python: can't find '__main__.py' in ''

Так что же здесь делает os.execl?И что означает это сообщение об ошибке?

Ответы [ 3 ]

6 голосов
/ 26 октября 2010

может быть, вы должны сделать это так:

os.execl(INTERP, *sys.argv) # don't pass again the interpreter path. 

Я думаю, что этот документ не так: http://wiki.dreamhost.com/Passenger_WSGI

о exec:

Функции exec UnixПодобные операционные системы представляют собой набор функций, которые приводят к полной замене запущенного процесса программой, передаваемой в качестве аргумента функции.

os.execl(path, arg0, arg1, ...)
os.execle(path, arg0, arg1, ..., env)
os.execlp(file, arg0, arg1, ...)
os.execlpe(file, arg0, arg1, ..., env)
os.execv(path, args)
os.execve(path, args, env)
os.execvp(file, args)
os.execvpe(file, args, env)

from: http://docs.python.org/library/os.html

Варианты функций lec и v функций exec * () отличаются тем, как передаются аргументы командной строки.С вариантами «l», пожалуй, легче всего работать, если число параметров фиксировано при написании кода;отдельные параметры просто становятся дополнительными параметрами для функций execl * ().Варианты «v» хороши, когда число параметров является переменным, а аргументы передаются в виде списка или кортежа в качестве параметра args.В любом случае аргументы дочернего процесса должны начинаться с имени выполняемой команды, но это не применяется.

Редактировать:

Я только что сделалчто вы делали в оболочке Python, и я получаю ту же ошибку:

>>> import os
>>> import sys
>>> os.execl('/home/login/projects/virtual/bin/python', '/home/login/projects/virtual/bin/python', *sys.argv)
/home/login/projects/virtual/bin/python: can't find '__main__.py' in ''
2 голосов
/ 05 ноября 2018

Я не собираюсь портить вопрос 9-летнего возраста, я недавно погуглил "пример Python execl" и наткнулся на эту ветку, почти заблудился от ответа, поэтому я пишу в надежде помочь другим посетителям.

Я согласен с https://stackoverflow.com/users/479633/mouad о способе воспроизведения ошибки, но не о причине, ошибка возникает из-за того, что когда интерпретатор python открывается интерактивно, sys.argv будет [''], поэтомупустая строка передается в вызванный execl интерпретатор python в качестве пути к основному сценарию (каталогу), поскольку основной файл сценария __main__.py не может быть найден в каталоге '' (текущий рабочий каталог), он жалуется на:

can't find '__main__.py' in ''

Я не могу понять, как https://stackoverflow.com/users/211075/monika-sulik удалось запустить скрипт python, при этом успешно установив первый член sys.argv в '', я полагаю, что код получил копию* передано в REPL.

Как https://stackoverflow.com/users/845210/bjmc, упомянутое в Python: os.execl () - что именно он делает?Почему я получаю эту ошибку? , документация правильная, нормально проходить путь интерпретатора дважды, хотя во второй раз не требуется.Сигнатура функции имеет корень в UNIX execve() API (https://linux.die.net/man/2/execve),, который говорит:

argv - массив строк аргументов, передаваемых новой программе.По соглашению, первая из этих строк должна содержать имя файла, связанное с исполняемым файлом.

Существуют программы, использующие это несоответствие, например busybox.

$ ln -s /bin/busybox cat
$ ./cat /etc/timezone
/UTC
$ python -c "import os; os.execl('./cat', 'cat', '/etc/timezone')"
/UTC
$ python -c "import os; os.execl('./cat', 'ls', '/etc/timezone')"
/etc/timezone

Несоответствиемежду путем к исполняемому файлу и argv[0] в main() затруднил получение надежного пути к исполняемому исполняемому файлу python (если не невозможно) в среде, подобной UNIX, вот сценарий, иллюстрирующий это:

import os
import sys


if len(sys.argv) >= 2 and sys.argv[1] == 'exec':
    os.execl('/usr/bin/python', 'ls', sys.argv[0])
else:
    print(sys.executable)
    print(sys.version)
    print(sys.argv)

Запустите этот скрипт

$ python test.py exec
/bin/ls
2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516]
['test.py']

и sys.executable имеет значение "/bin/ls", как указано в документации (https://docs.python.org/3/library/sys.html#sys.executable) говорит

Строка, дающаяабсолютный путь исполняемого двоичного файла для интерпретатора Python, в системах, где это имеет смысл .

примерно sys.executable, если разработчики Python не могут понять, как получить sys.executableуказать путь к исполняемому исполняемому файлу python, вероятно, в UNIX-подобной среде это не имеет смысла.Буду признателен, если кто-нибудь скажет мне иначе.

0 голосов
/ 26 октября 2010
>>> import os
>>> help(os.execl)


execl(file, *args)
    execl(file, *args)

    Execute the executable file with argument list args, replacing the
    current process.

Это может помочь с вашей проблемой: http://ubuntuforums.org/showthread.php?t=1493979

...