Python Forum

Full Version: re-open a Popen pipe in non-binary mode
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i did some experimenting and found that i can exploit open()'s ability to open a file descriptor as a file to change the mode of a pipe from subprocess.Popen() or os.pipe(). here is how i tried it:

#!/usr/bin/env python3

import os
from subprocess import PIPE,Popen

proc = Popen(['bash','-c','exec xz -9 >tryout.xz'],stdin=PIPE)
ofd = proc.stdin.fileno()
prt = open(ofd,'w')
print('foobar',file=prt)
prt.close()
proc.wait()

proc = Popen(['bash','-c','exec xzdec <tryout.xz'],stdout=PIPE)
ifd = proc.stdout.fileno()
look = open(ifd,'r')
lines = look.readlines()
print(repr(lines))
look.close()
proc.wait()
so, i don't need to convert to bytes to output to a pipe, and can input a regular string from a pipe. i assume anything else that comes as a binary mode file can be done the same.
You can reuse the already opened Pipe.

Here two different approaches:

import os
import subprocess
import io

# Low Level approach
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
proc.stdin.fileno()
tw = os.fdopen(proc.stdin.fileno(), 'w', encoding='utf8')
tw.write('Hello World\n')
tw.flush()
proc.stdin.write(b'Hello World bytes\n')
proc.stdin.flush()
proc.stdin.close()

# tw is now also closed.

# different approach with io
proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE)
tw2 = io.TextIOWrapper(proc.stdin, encoding='utf8')
tw2.write('Hello ...\n')
tw2.flush()
proc.stdin.write(b'Bin ...\n')
proc.stdin.flush()

tw2.close()
# will close also proc.stdin
The command cat reads from stdin.
It prints the data on the screen, when the pipe stdin was closed.
the idea is that i wanted to switch the mode from binary to non-binary to be able to write/print regular strings to it or visa-versa. this quest was the result of the uncertainty of bytes vs. str from pickle. but, it is still a broadly usable capability, especially in using pipes i get from Popen since i expect to do that often.