Mon*_*lik 2 python virtualenv 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)
Run Code Online (Sandbox Code Playgroud)
我理解的前三行,但我对第四行只有一个含糊不清的想法,那就是碰巧给我一个错误:
/home/login/.virtualenvs/env_name/bin/python: can't find '__main__.py' in ''
那么os.execl到底在做什么呢?那个错误信息意味着什么?
我无意搞乱一个 9 年前的问题,我很快在谷歌上搜索了“Python execl example”并偶然发现了这个帖子,几乎被答案误导了,所以我发帖希望能帮助其他访问者。
我同意/sf/users/33574341/关于重现该错误的方式,但不同意原因,发生错误是因为当交互式打开python解释器时,sys.argv将[''],因此传递了一个空字符串到 execl 调用的 python 解释器作为主脚本(目录)的路径,由于在目录 '' (当前工作目录)中找不到主脚本文件 __main__.py,它会抱怨:
can't find '__main__.py' in ''
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚/sf/users/14775281/sys.argv如何在成功设置to的第一个成员的同时设法运行 python 脚本'',这是我的纯粹猜测,代码被复制粘贴到 REPL 。
正如/sf/users/59164731/在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
Run Code Online (Sandbox Code Playgroud)
argv[0]可执行文件路径和in之间的不一致main()使得在类 UNIX 环境中获取正在运行的 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)
Run Code Online (Sandbox Code Playgroud)
运行这个脚本
$ python test.py exec
/bin/ls
2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516]
['test.py']
Run Code Online (Sandbox Code Playgroud)
并且sys.executable具有价值"/bin/ls",正如文档(https://docs.python.org/3/library/sys.html#sys.executable)所述
在有意义的系统上,给出 Python 解释器的可执行二进制文件的绝对路径的字符串。
关于sys.executable,如果 python 开发人员无法弄清楚如何指向sys.executable正在运行的 python 可执行文件的路径,那么它在类 UNIX 环境中可能没有意义。如果有人告诉我其他情况,我将不胜感激。
也许你应该这样做:
os.execl(INTERP, *sys.argv) # don't pass again the interpreter path.
Run Code Online (Sandbox Code Playgroud)
我认为这个文档是错误的:http://wiki.dreamhost.com/Passenger_WSGI
关于执行官:
类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)
Run Code Online (Sandbox Code Playgroud)
来自: 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 ''
Run Code Online (Sandbox Code Playgroud)
kan*_*aka -3
>>> import os
>>> help(os.execl)
execl(file, *args)
execl(file, *args)
Execute the executable file with argument list args, replacing the
current process.
Run Code Online (Sandbox Code Playgroud)
这可能有助于解决您的问题:http://ubuntuforums.org/showthread.php ?t=1493979
| 归档时间: |
|
| 查看次数: |
17195 次 |
| 最近记录: |