If you're like me, when you first starting using
subprocess.Popen you would inherently think that you can invoke any kind of command using this.
But, No! it won't
subprocess.Popen doesn't allocate a pseudo terminal during its run. That means some command might not run. To name one, it is
ssh -t (with pseudo terminal allocated) it just won't run and will raise an exception.
Some others still run without a pseudo terminal, however it might not really like what you have seen using it under the Terminal.app (or others of that kind). For example,
docker pull command supports both with and without terminal. But its output's gonna be different. If you can recall, the normal output of it has progress bars of some sort, this is not the case for running
docker pull without pseudo terminal.
This simple fact, however, took me days to figure out. I was trying to duplicate the
subprocess.Popen at the time. Regardless of my efforts, I cannot see the progress bars of the
docker pull command (I just read output from the
subprocess.PIPE and put it into many ends). That astonished me greatly.
I wasn't sure at the time whether I did it right or not. Maybe control characters (in order to create progress bars you need these guys) just won't go through the pipe. It turned out that was bullshit, every control characters are represented in bytes and WILL go through the pipe if there is any.
Finally, I found that it is the
docker it self that changes the output pattern when it finds that it's not being run with a pseudo terminal. And yes, my puny pipe is not a kind of pseudo terminal, so progress bars are not in the output.