4

I have already read the documentation about subprocesses in python, but still cannot quite understand this.

When using Popen, and we set the parameter stdout (or stdin) to subprocesses.PIPE, what does that actually mean?

The documentation says

stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively... PIPE indicates that a new pipe to the child should be created.

what does this mean?

For example, if I have two subprocesses both with stdout to PIPE, are the ouptuts mixed? (I don't think so)

more importantly, if I have a subprocess with stdout set to PIPE and later another subprocess with stdin set to PIPE , is that pipe the same, the output of one goes to the other?

Can someone explain me that part of the documentation that seems criptic to me?


Additional notes: For example

import os
import signal
import subprocess
import time

# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before  exec() to run the shell.
pro = subprocess.Popen("sar -u 1 > mylog.log", stdout=subprocess.PIPE, 
                       shell=True, preexec_fn=os.setsid) 

// Here another subprocess
subprocess.Popen(some_command, stdin=subprocess.PIPE)
time.sleep(10)

os.killpg(os.getpgid(pro.pid), signal.SIGTERM) 

Does the output of sar goes as input to "some command"?

KansaiRobot
  • 7,564
  • 11
  • 71
  • 150
  • 1
    A "pipe" is simply something with two ends - one end can be written to, the other end can be read from. Typically, the ends are used in two separate processes, but this isn't actually required. Each pipe you create is entirely separate; if you wanted to connect two subprocesses, you'd pass the `stdout` returned from one as the `stdin` of the other. – jasonharper Jun 09 '20 at 15:43
  • what happens if I don't put the argument? – KansaiRobot Jun 09 '20 at 20:49
  • Re: the question about whether output to pipes gets mixed -- it does say a *new* pipe. Just like every time you use `|` in shell, every time you use PIPE with `subprocess` you get a new, independent FIFO pair. – Charles Duffy Jun 09 '20 at 23:48
  • And it really is _exactly_ like using `|` in shell. Think of it the same way and you'll be in a good place. – Charles Duffy Jun 09 '20 at 23:49
  • BTW, `sar -u 1 > mylog.log` is an exceptionally bad example, because the `>` makes the shell you're starting ignore the pipe that Python gives it on stdin at time of invocation, and redirect output to `mylog.log` instead. `stdout=` is most useful with `shell=False`, which is what people should use absent an extremely compelling reason to do otherwise. – Charles Duffy Jun 09 '20 at 23:52
  • @CharlesDuffy on stdin? but in the parameters only stdout is being set to PIPE...(confused) – KansaiRobot Jun 09 '20 at 23:56
  • by the way see https://stackoverflow.com/a/4791612/4451521 where shell = True and stdout is used – KansaiRobot Jun 09 '20 at 23:57
  • I said "most useful". They _can_ be used together, but you need it most when you don't have a shell, because without a shell there's nothing to (for example) open an output file for you. – Charles Duffy Jun 10 '20 at 00:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/215625/discussion-between-charles-duffy-and-kansairobot). – Charles Duffy Jun 10 '20 at 00:07
  • Note that you *could* make your second subprocess read its input from the first subprocess's output, if (1) you used `stdin=pro.stdout` when starting that second subprocess, (2) you didn't use `>mylog.log`, and (3) you closed the parent Python shell's copy of `pro.stdout` before waiting for the second process to exit. – Charles Duffy Jun 10 '20 at 00:13
  • (For details beyond that, really, read and respond in the chat discussion linked above; I don't know with any certainty what it is you're asking that the existing answer doesn't cover, but hopefully the additional explanation helps; if it doesn't, *you* need to explain, in detail, what you understand the documentation to mean or precisely which aspect of it is unclear, so we can figure out how and why restating it is failing to be an adequate answer). – Charles Duffy Jun 10 '20 at 00:14

1 Answers1

-1

Please see the document.

So as you can see, the PIPE is a special value, it "indicates that a new pipe to the child should be created." Which means, stdout=subprocess.PIPE and stderr=subprocess.PIPE results in two different pipes.

And for your example, the answer is no. These are two different pipes.

Actually you can print out the subprocess.PIPE:

print(subprocess.PIPE)
# -1
print(type(subprocess.PIPE))
# int
# So it is just an integer to represent a special case.
Sraw
  • 18,892
  • 11
  • 54
  • 87
  • what happens if I don't set the argument stdout (in my example for instance)? – KansaiRobot Jun 09 '20 at 20:48
  • See the document: "With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent." – Sraw Jun 09 '20 at 21:02
  • seeing the document does not help. I already did(I wrote that in the question). My question is if someone can explain that to me – KansaiRobot Jun 09 '20 at 23:37
  • Your question about the `PIPE` has been answered in my answer. And I have also answered your question about the default settings. The child process will inherit the parent's filehandles. If you don't understand what does it mean, please create another question, let's focus on one problem per question. – Sraw Jun 09 '20 at 23:45