Search code examples
pythoniopiping

What's the most hassle-free way to pipe stuff through a short-running process and get output?


I want to run lessc on some stuff I've read/processed through lessc, and don't want to mess around with files. subprocess.check_output and Popen.communicate have both proven to be a great deal of hassle for something that was meant to be a quick tweak. Neither of them output anything/waits forever. Is there some sort of hassle-free convenience function that manages buffers and whatnot?

Example source:

from subprocess import Popen
from sys import stderr

s = """
@a: 10px
foo {
    width: @a;
}
"""
print("making")
p = Popen("lessc -", shell=True, stdout=-1, stdin=-1, stderr=stderr)
print("writing")
p.stdin.write(bytes(s, "utf-8"))
print("Waiting")
p.wait()
print("readng")
out = p.stdout.read()
print(out)

Output:

making
writing
Waiting

(Commenting out the wait part just makes it block on reading)


Solution

  • I'm guessing that the problem is simply that your lessc is not short-lived. It's reading from its stdin, which you never close.

    How would lessc behave in a terminal if you had it reading from stdin, typed some input at it, then simply waited (never signalling end of input)? That's what your program is doing.