3
votes

I currently have this code that pipe stdout or stderr following the context:

def execteInstruction(cmd, outputNumber):
  do_stdout = DEVNULL
  do_stderr = DEVNULL
  if outputNumber != 2:
    do_stdout = subprocess.PIPE
  else:
    do_stderr = subprocess.PIPE
  return subprocess.Popen(cmd, shell=True, stderr=do_stderr, stdout=do_stdout)

And then I read the result with communicate(). This works perfectly well except that I need to read a custom fd because I'm using subprocess to run a command that output on the file descriptor 26.

I have seen code that write to another fd than stdout or stderr, but none that read from a custom fd. So how can I pipe a custom fd from subprocess.Popen ?

1
I do not get what you want to do: Do you want to access the fd of stdout/stderr directly? or do you need to access a new fd, created by the child process? If so, what type of cmd are you running and can you provide the new fd to the cmd? And are you running on a specific plateform? subprocess behave differently on windows/unix... - Thomas Moreau

1 Answers

1
votes

Since I needed an answer to this, here's a much belated answer for others:

To implement a similar use of additional fds in Python, I came up with this code:

import os, subprocess

read_pipe, write_pipe = os.pipe()
xproc = subprocess.Popen(['Xephyr', '-displayfd', str(write_pipe)],
                         pass_fds=[write_pipe])

display = os.read(read_pipe, 128).strip()

I think os.dup2(write_pipe, 26) before the Popen constructor combined with pass_fds=[26] would do that last step of getting you a specific fd number, rather than just whatever os.pipe chose, but I haven't tested it.

If nothing else, it should be possible to redirect fd 26 to whatever write_pipe turns out to be if you use subprocess.Popen to call a shell-script wrapper which runs exec 26>$WHATEVER before calling the actual target command.