When Using Os.Execlp, Why 'Python' Needs 'Python' as Argv[0]

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



Leave a reply



Submit