2

for a little project of my own, I am trying to write a program that prints out the contents of a file on the computers default printer. I know theres alot of similar questions around, but none of them works on my pc (Linux mint 17.3)

here is one that I tried, it got the closest to what i needed:

from subprocess import Popen
from cStringIO import StringIO

# place the output in a file like object
sio = StringIO("test.txt")

# call the system's lpr command
p = Popen(["lpr"], stdin=sio, shell=True)
output = p.communicate()[0]

this gives me the following error:

Traceback (most recent call last):
  File "/home/vandeventer/x.py", line 8, in <module>
    p = Popen(["lpr"], stdin=sio, shell=True)
  File "/usr/lib/python2.7/subprocess.py", line 702, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "/usr/lib/python2.7/subprocess.py", line 1117, in _get_handles
    p2cread = stdin.fileno()
AttributeError: 'cStringIO.StringI' object has no attribute 'fileno'

Doe anyone out there know hoe one could implement this in python? it really does not have to work on windows

Regards

Cid-El

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Cid-El
  • 500
  • 7
  • 30

1 Answers1

3

you don't have to use StringIO for this. Just use the pipe feature of subprocess and write your data to p.stdin:

from subprocess import Popen
# call the system's lpr command
p = Popen(["lpr"], stdin=subprocess.PIPE, shell=True)  # not sure you need shell=True for a simple command
p.stdin.write("test.txt")
output = p.communicate()[0]

as a bonus, this is Python 3 compliant (StringIO has been renamed since :))

BUT: that would just print a big white page with one line: test.txt. lpr reads standard input and prints it (that's still an interesting piece of code :))

To print the contents of your file you have to read it, and in that case it's even simpler since pipe & files work right away together:

from subprocess import Popen
with open("test.txt") as f:
  # call the system's lpr command
  p = Popen(["lpr"], stdin=f, shell=True)  # not sure you need shell=True for a simple command
  output = p.communicate()[0]
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219