我在使用virtualenv在passenger_wsgi模块上部署Django时遇到了一些麻烦。 passenger_wsgi.py文件中的Python代码应该解决我的问题:
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到底在做什么呢?那个错误信息意味着什么?
答案 0 :(得分:5)
也许你应该这样做:
os.execl(INTERP, *sys.argv) # don't pass again the interpreter path.
我认为这个文档错了:http://wiki.dreamhost.com/Passenger_WSGI
关于exec:
类Unix操作系统的exec函数是一组函数,它们使运行过程完全被作为函数参数传递的程序所取代。
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)
来自: http://docs.python.org/library/os.html
exec *()函数的“l”和“v”变体在命令行参数的传递方式上有所不同。如果在编写代码时参数的数量是固定的,那么“l”变体可能是最容易使用的;各个参数只是成为execl *()函数的附加参数。当参数的数量是可变的时,“v”变体是好的,参数在列表或元组中作为args参数传递。在任何一种情况下,子进程的参数都应该从正在运行的命令的名称开始,但不会强制执行。
修改强>
我刚刚在python shell中做了你正在做的事情,我得到了同样的错误:
>>> 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 ''
答案 1 :(得分:1)
我不是要搞一个9岁的问题,我不久后在Google上搜索了“ Python execl示例”并碰到了这个线程,几乎被答案所迷惑,所以我发帖希望对其他访问者有所帮助。
我同意https://stackoverflow.com/users/479633/mouad的错误重现方式,但并非如此,原因是发生错误是因为以交互方式打开python解释器时,sys.argv
将是['']
,因此一个空字符串作为主脚本(目录)的路径传递给调用execl的python解释器,因为在目录``(当前工作目录)中找不到主脚本文件__main__.py,它抱怨:< / p>
can't find '__main__.py' in ''
我无法弄清楚https://stackoverflow.com/users/211075/monika-sulik如何成功地将sys.argv
的第一个成员设置为''
时运行了python脚本,这纯粹是我的代码被复制粘贴了。到REPL。
正如https://stackoverflow.com/users/845210/bjmc中提到的Python: os.execl() - what does it do exactly? Why am I getting this error?一样,文档是正确的,可以两次通过解释器路径,尽管第二次不需要。该函数的签名的根源是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
在类似UNIX的环境中,可执行文件路径与argv[0]
中的main()
之间的不一致使得很难获得(即使不是不可能)通往正在运行的python可执行文件的可靠路径,这是一个脚本来说明这一点:
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的环境中可能没有意义。如果有人另外告诉我,我将不胜感激。
答案 2 :(得分:-1)
>>> 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