os.execl 到底做了什么?为什么我会收到此错误?
我在使用 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:在“”中找不到“__main__.py”
那么 os.execl 到底在做什么呢?该错误消息是什么意思?
I'm running into some trouble with deploying Django on the passenger_wsgi module with virtualenv. The Python code in the passenger_wsgi.py file, which should fix my problem is:
import os, sys
INTERP = '/home/login/.virtualenvs/env_name/bin/python'
if sys.executable != INTERP:
os.execl(INTERP, INTERP, *sys.argv)
The first three lines I understand, but I only have a very vague idea about the fourth one and that's the one that happens to be giving me an error:
/home/login/.virtualenvs/env_name/bin/python: can't find '__main__.py' in ''
So what is os.execl doing here exactly? And what does that error message mean?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我无意搞乱一个 9 年前的问题,我很快在谷歌上搜索了“Python execl example”并偶然发现了这个帖子,几乎被答案误导了,所以我发帖希望能帮助其他访问者。
我同意 https://stackoverflow.com/users/479633/mouad 关于重现该错误的方法,但不同意发生错误的原因是,当以交互方式打开Python解释器时,
sys.argv
将是['']
,因此一个空字符串被传递给execl调用python解释器作为主脚本(目录)的路径,由于在目录''(当前工作目录)中找不到主脚本文件__main__.py,它抱怨:我无法弄清楚如何 https://stackoverflow.com/users/211075/monika-sulik 设法运行 python 脚本,同时成功设置 < 的第一个成员code>sys.argv 到
''
,我纯粹猜测代码被复制粘贴到了 REPL。正如 https://stackoverflow.com/users/845210/bjmc 中提到的.com/questions/4025442/python-os-execl-what-does-it-do-exactly-why-am-i-getting-this-error#comment37742802_4025513">Python:os.execl() - 它有什么作用确切地?为什么我会收到此错误?,文档是正确的,可以传递解释器路径两次,但不需要第二次。该函数的签名源于 UNIX
execve()
API ( https://linux.die.net/man/2/execve),其中表示:有些程序利用了这种不一致性,例如 busybox。
可执行文件路径和 main() 中的 argv[0] 之间的不一致使得在类 UNIX 环境,这里有一个脚本来说明这一点:
运行此脚本
,
sys.executable
的值为"/bin/ls"
,如文档 (https://docs.python.org/3/library/sys.html#sys。可执行文件)说关于 sys.executable ,如果 python 开发人员无法弄清楚如何让 sys.executable 指向正在运行的 python 可执行文件的路径,那么它可能没有意义类 UNIX 环境。如果有人告诉我其他情况,我将不胜感激。
It's not my intention to mess up with a question 9 years old, I googled "Python execl example" shortly and bumped into this thread, almost got misled by the answer, so I'm posting in hope of helping other visitors.
I agree with https://stackoverflow.com/users/479633/mouad about the way to reproduce the bug, but not the reason, the error occurs because when a python interpreter is opened interactively,
sys.argv
will be['']
, so an empty string is passed to the execl-invoked python interpreter as the path to the main script (directory), since the main script file __main__.py cannot be found in directory '' (the current work directory), it complains about:I can not figure out how https://stackoverflow.com/users/211075/monika-sulik managed to run a python script while successfully set the first member of
sys.argv
to''
, it's my pure guess that the code got copy-pasted to the REPL.As https://stackoverflow.com/users/845210/bjmc mentioned in Python: os.execl() - what does it do exactly? Why am I getting this error?, the documentation is correct, it's OK to pass the interpreter path twice, although not required the second time. The signature of the function has its root in the UNIX
execve()
API (https://linux.die.net/man/2/execve), which says:There are programs taking advantage of this inconsistency, e.g. busybox.
The inconsistency between the executable path and the
argv[0]
inmain()
has made getting the reliable path to the running python executable very hard (if not impossible) in a UNIX-like environment, here is a script to illustrate this:Run this script
and
sys.executable
has value"/bin/ls"
, as the documentation (https://docs.python.org/3/library/sys.html#sys.executable) saysabout
sys.executable
, if the python developers cannot figure out how to getsys.executable
point to the path of the running python executable, it probably does not make sense in a UNIX-like environment. I would be grateful if someone tells me otherwise.也许你应该这样做:
我认为这个文档是错误的: http://wiki.dreamhost.com/Passenger_WSGI< /a>
关于 exec:
类 Unix 操作系统的 exec 函数是函数的集合,这些函数使正在运行的进程完全被作为参数传递给函数的程序替换。
来自: http://docs.python.org/library/os. exec
*() 函数的“l”和“v”变体在传递命令行参数的方式上有所不同。如果编写代码时参数的数量是固定的,“l”变体可能是最容易使用的;各个参数只是成为 execl*() 函数的附加参数。当参数数量可变时,“v”变体非常有用,并且参数作为 args 参数在列表或元组中传递。无论哪种情况,子进程的参数都应以正在运行的命令的名称开头,但这不是强制的。
编辑:
我刚刚做了你在 python shell 中所做的事情,但我得到了同样的错误:
maybe you should do it like this:
i think this doc is wrong : http://wiki.dreamhost.com/Passenger_WSGI
about exec:
The exec functions of Unix-like operating systems are a collection of functions that causes the running process to be completely replaced by the program passed as an argument to the function.
from : http://docs.python.org/library/os.html
The “l” and “v” variants of the exec*() functions differ in how command-line arguments are passed. The “l” variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the individual parameters simply become additional parameters to the execl*() functions. The “v” variants are good when the number of parameters is variable, with the arguments being passed in a list or tuple as the args parameter. In either case, the arguments to the child process should start with the name of the command being run, but this is not enforced.
Edit:
i just did what you were doing in a python shell and i get the same error:
这可能有助于解决您的问题: http://ubuntuforums.org/showthread.php?t=1493979< /a>
This might help with your problem: http://ubuntuforums.org/showthread.php?t=1493979