When using os.execlp, why `python` needs `python` as argv[0]
When python is executed, it creates sys.argv
for you. The values in that list are based on the arguments passed to it by the operating system, but it leaves off the sys.executable
value from that list.
In other words, when Python is invoked, it sets sys.argv
to everything but it's own executable.
When you invoke a new executable via os.execlp()
, you still need to include Python in that as that is what executable that the OS will run. The first two values of what you a pass to os.execlp()
are still required, whatever you find in sys.argv
later on.
execlp() in python
The first argument is the program to execute (found on the PATH
). The rest are the sys.argv
arguments to the program.
The first such argument is the program name used to invoke it, and the display value used in the OS process list. It is the value of sys.argv[0]
in a python script.
I'm having trouble running os.execl() with python 3
The first argument to os.execl()
should be the path to the executable that you want to run. It won't search for it using $PATH
.
You also need to repeat the name of the program as arg0
.
os.execl('/usr/local/bin/python', 'python', "test.py", *sys.argv)
You can use os.execlp()
to use $PATH
to find the program automatically.
os.execlp('python', 'python', "test.py", *sys.argv)
BTW, sys.argv[0]
will be the name of the original Python script. You might want to remove that when passing arguments along to another script, so you would use *sys.argv[1:]
.
And of course, most people use the subprocess
module to execute other programs, rather than using fork
and exec
directly. This provides higher level abstractions to implement I/O redirection, waiting for the child process, etc.
Replace current process with invocation of subprocess?
You may be interested in os.execv()
and friends:
These functions all execute a new program, replacing the current
process; they do not return. On Unix, the new executable is loaded
into the current process, and will have the same process id as the
caller. Errors will be reported as OSError exceptions.
Unable to use execvp to run a python3 file from a C file? (macOS)
char** const args[] = {argv};
Creates variable that is an array to variables with the type being pointer to pointer to character. The array has one element, ie. it stores one element of pointer to pointer to character type. This one element has the value of the argv pointer, ie. the value of &argv[0]
(not argv[0]
). args
is an array of variables that have pointer to pointer to character type. args
is not a "copy of all memory referenced by argv" thing. args
is a single element array.
args
In most context array of type decays into pointer of type. So args
decays to pointer to pointer to pointer to character, ie. is has char ***
type. Note that to the value args == &args
and that args != &argv
. The address of args
array is not equal to argv
.
Calling execvp
with non-compatible arguments is undefined behavior so anything can happen. Enable compiler warnings and fix them every time, so that no undefined behavior happens in your program.
What you want, is that to create a copy of all values of pointers inside argv
array. You need also a space for NULL terminator. So first allocate the memory for values of all pointers inside argv
array of argc
count pointers to strings. Then copy the values of pointers inside argv
array. NULL terminate the array. Then call execvp
.
// allocate space
char **args = calloc(sizeof(char*), argc + 1);
// copy pointers
for (size_t i = 0; i < argc; ++i) {
args[i] = argv[i];
}
// alternatively copy values using memcpy
memcpy(args, argv, sizeof(char*) * argc);
// null terminate
args[argc] = NULL;
execvp("./test.py", args);
// and always remember to pick up the trash
free(args);
Python: How can I execute a jar file through a python script
I would use subprocess this way:
import subprocess
subprocess.call(['java', '-jar', 'Blender.jar'])
But, if you have a properly configured /proc/sys/fs/binfmt_misc/jar
you should be able to run the jar directly, as you wrote.
So, which is exactly the error you are getting?
Please post somewhere all the output you are getting from the failed execution.
How to g_spawn (GLib) a Python script from a C program
The solution is using:
gchar* argv[] = {"python3", "../gtk_simple_plot/plot.py", NULL};
with the addition of G_SPAWN_SEARCH_PATH
in the default spawn settings, such that the g_spawn call now looks like this:
// Spawn the python program to plot
spawn_success =
g_spawn_async_with_pipes (NULL, // Inherit parent's working directory
argv, // argv from above
NULL, // Don't set any additional environment variables
G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, // Default spawn settings
NULL, // No setup function prior to executing
NULL, // No data passed to setup function
&transition_pid, // Store child pid
NULL, // No standard input file descriptor
&stdoutFD, // Standard output file descriptor
&stderrFD, // Standard error file descriptor
&err); // Store error
This flag specifies that argv[0]
need not be an absolute path, it will be looked for in the user's PATH
.
How to pass socket variable while using exec() in Python?
On unix-like systems execve
programs retain open file descriptors that are not marked FD_CLOEXEC
. You need to pass the file descriptor (a small integer) to the new process. Python sets file descriptors to close-on-exec by default, so if your parent is a python process, it needs to specifically change that flag. You can write the socket fd to a file:
open("file1.txt", "w").write(str(s.fileno()))
but more commonly, one would either pass it on the command line or tuck it into the environment. As an example of python calling python with the socket passed on the command line:
verA.py
import socket
import os
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("stackoverflow.com", 80))
os.set_inheritable(sock.fileno(), True)
os.execlp(sys.executable, "python", "verB.py", str(sock.fileno()))
verB.py
import socket
import sys
sock = socket.fromfd(int(sys.argv[1]), socket.AF_INET, socket.SOCK_STREAM)
sock.send(b"GET / HTTP/1.1\r\nHost:stackoverflow.com\r\n\r\n")
print(sock.recv(500))
How can I make my script choose the right python interperter?
Please use virtualenv, which makes isolated Python environments easy.
Related Topics
How to Delete a File or Folder in Python
Schedule Python Script with Crontab
Allowing Ctrl-C to Interrupt a Python C-Extension
Asyncio in Corroutine Runtimeerror: No Running Event Loop
Permission Denied When Executing Python File in Linux
How to Default Python3.8 on My MAC Using Homebrew
How to Run Multiple Subprocesses via Fork()
How to Import Lldb in a Python Script
Python Shutil.Copy Fails on Fat File Systems (Ubuntu)
How to Push a Subprocess.Call() Output to Terminal and File
Mismatch Between Sys.Executable and Sys.Version in Python
Pyserial Works Fine in Python Interpreter, But Not Standalone