Jesse Shieh
Jesse Shieh

Reputation: 4850

Python execv and pipe output

I'd like to use Python's os.execv to replace my current process, but I also want the new process to send stdout to another process (to collect logs and ship them over the network). The process collecting logs also needs to be started by the original Python process.

I'm guessing I need to do some fork, dup2, execv stuff, but I need some help.

In bash, it might look something like this

#!/bin/bash
exec ./foo ∣ ./bar

Upvotes: 4

Views: 1203

Answers (1)

ephemient
ephemient

Reputation: 204668

You can set up the pipe and processes this way.

import os

(read_fd, write_fd) = os.pipe()
pid = os.fork()
if pid == 0:
    os.dup2(read_fd, 0)
    os.close(read_fd)
    os.close(write_fd)
    os.execlp('./bar', './bar')
    os._exit(-1)  # in case exec fails
os.close(read_fd)
os.dup2(write_fd, 1)
os.close(write_fd)
os.execlp('./foo', './foo')

It's still convenient to use subprocess though, at least for the first part.

import os
import subprocess

p = subprocess.Popen(['./bar'], stdin=subprocess.PIPE)
os.dup2(p.stdin.fileno(), 1)
p.stdin.close()
os.execlp('./foo', './foo')

Upvotes: 4

Related Questions