Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does os.execl do exactly? Why am I getting this error?

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?

like image 564
Monika Sulik Avatar asked Oct 26 '10 15:10

Monika Sulik


People also ask

What is os execl in Python?

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. os.execl(path, arg0, arg1, ...)

What does os module do in Python?

Python OS module provides the facility to establish the interaction between the user and the operating system. It offers many useful OS functions that are used to perform OS-based tasks and get related information about operating system. The OS comes under Python's standard utility modules.

What is import os Python?

system. Python os system function allows us to run a command in the Python script, just like if I was running it in my shell. For example: import os currentFiles = os.system("users > users.txt")

How do I open a file in Python os?

Opening files To open a file using the Python OS module, you need to import the OS module, then call the system() method and pass it the path of your file. It's important to recognize that the system() command doesn't open a file behind the scenes for reading or writing (file I/O).


2 Answers

maybe you should do it like this:

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

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.

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

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:

>>> 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 ''
like image 172
mouad Avatar answered Nov 06 '22 06:11

mouad


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:

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

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:

argv is an array of argument strings passed to the new program. By convention, the first of these strings should contain the filename associated with the file being executed.

There are programs taking advantage of this inconsistency, e.g. 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

The inconsistency between the executable path and the argv[0] in main() 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:

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 this script

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

and sys.executable has value "/bin/ls", as the documentation (https://docs.python.org/3/library/sys.html#sys.executable) says

A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense.

about sys.executable, if the python developers cannot figure out how to get sys.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.

like image 45
coinfaces Avatar answered Nov 06 '22 05:11

coinfaces