Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: subprocess equivalent for "os.execvp()"?

68 views
Skip to first unread message

Chris Angelico

unread,
Jan 8, 2023, 5:52:55 AM1/8/23
to
On Sun, 8 Jan 2023 at 21:51, <c.b...@posteo.jp> wrote:
>
> Hello,
>
> is there an equivalent in the subprocess module for "os.execvp()" to
> replace the current process with the new called one?

It won't make a subprocess, so no. It's in the os module - under the
name execvp. You found it already :)

ChrisA

Eryk Sun

unread,
Jan 8, 2023, 11:22:58 AM1/8/23
to
On 1/8/23, c.b...@posteo.jp <c.b...@posteo.jp> wrote:
>
> is there an equivalent in the subprocess module for "os.execvp()" to
> replace the current process with the new called one?

A note for Windows users

Avoid using any of the `os.exec*` functions on Windows. There's no
support for replacing a Windows process image, so the `exec*()`
functions simply spawn a child process and terminate the current one.
This is a mess in general because a waiting parent isn't aware of the
spawned descendant. It's particularly bad for a console process that
inherits the console session, since two processes will try to use
console I/O simultaneously.

c.b...@posteo.jp

unread,
Jan 9, 2023, 3:36:52 AM1/9/23
to
Dear Eryk,

Am 08.01.2023 17:22 schrieb Eryk Sun:
> Avoid using any of the `os.exec*` functions on Windows. There's no
> support for replacing a Windows process image, so the `exec*()`
> functions simply spawn a child process and terminate the current one.

Thanks for bringing this up.

On Python for Windows what is the appropriate way how a process can call
itself again?

Let me give you an example [1]:
There is a project "bitcli" having two entry points

[project.scripts]
bitcli = "bitcli.__main__:main"
bitcli-root = "bitcli.__main__:run_main_as_root_via_policykit"

The first is usual.

But the second does call "bitcli" via "pkexec" to give it some root
rights.

This application is intended to be run as user or root by the user
himself.

def run_main_as_root_via_policykit():
cmd = ['pkexec', '--disable-internal-agent', 'bitcli']

# See https://github.com/python/cpython/issues/39569
os.execvp(cmd[0], cmd)

Is there a better way to achiev this?

[1] -- <https://codeberg.org/buhtz/bit_demo>

Eryk Sun

unread,
Jan 9, 2023, 5:32:42 AM1/9/23
to
On 1/9/23, c.b...@posteo.jp <c.b...@posteo.jp> wrote:
>
> On Python for Windows what is the appropriate way how a process can call
> itself again?
>
> Let me give you an example [1]:
> There is a project "bitcli" having two entry points
>
> [project.scripts]
> bitcli = "bitcli.__main__:main"
> bitcli-root = "bitcli.__main__:run_main_as_root_via_policykit"
>
> The first is usual.
>
> But the second does call "bitcli" via "pkexec" to give it some root
> rights.
>
> This application is intended to be run as user or root by the user
> himself.
>
> def run_main_as_root_via_policykit():
> cmd = ['pkexec', '--disable-internal-agent', 'bitcli']
>
> # See https://github.com/python/cpython/issues/39569
> os.execvp(cmd[0], cmd)

The nearest equivalent on Windows, if the current process doesn't have
administrator access and high integrity level, would be to spawn a
process with administrator access and elevated integrity level by
calling ShellExecuteExW() with the "runas" operation. The original
process should wait on the spawned process and proxy its exit status.
It should also add the spawned process to a kill-on-close,
silent-breakaway job, such that terminating the original process also
terminates the spawned process.

The standard library doesn't support calling ShellExecuteExW() or
working with job objects, except via ctypes. Or use the PyWin32
package.
0 new messages