Joshua Eric Turcotte
Joshua Eric Turcotte

Reputation: 435

why is subprocess.call() not running command as anticipated?

bit of a niche scenario here, and to test directly you'll need wkhtmltopdf (in this case listening to port 7000 w/ --read-args-from-stdin) up and running as a daemon (and a handy html file on hand.)

if I do:

echo "-s letter -T 24mm -R 24mm -B 0mm -g ~/my.html /tmp/my.pdf" | nc localhost 7000

then very swiftly out pops /tmp/my.pdf ... I can do this 25 times in a row and get as many results as if I spun wkhtmltopdf up and down 25 times separately.

Walp, that means I need to be able to call THIS from within our own queue-eating daemon and, further, I have to wait for it to finish before checking for the presence of results and ticking of successes or failures accordingly.

I found subprocess.call, but it's not working for reasons unspecified... to wit, from the python prompt:

call(['echo', '\"-s letter -T 24mm -R 24mm -B 0mm -g ~/my.html /tmp/my1.pdf\"', '|', 'nc', 'localhost', '7000'])

I get:

"-s letter -T 24mm -R 24mm -B 0mm -g ~my.html /tmp/my1.pdf" | nc localhost 7000
0

the 0 suggests it THINKs it was successful... but, unlike when I do the identical statement from the bash itself, nothing comes out of the wkhtmltopdf daemon. I tried sticking an extra 'echo ' in there since the printout doesn't include it, but same result.

So... somehow, this is not engaging things in the same way that is done when typed directly into the bash prompt.

Ideas? Expertise?

Thanks!

Upvotes: 1

Views: 176

Answers (1)

glglgl
glglgl

Reputation: 91049

To solve your problem, calling echo and nc via the shell is a viable, but unpractical way.

Instead, I would do

def call_7000(*a):
    import socket
    s = socket.create_connection(('localhost', 7000))
    s.write(" ".join(str(i) for i in a)
    s.close()

which you now can call as

call_7000("-s letter -T 24mm -R 24mm -B 0mm -g ~my.html /tmp/my1.pdf")

or as

(Except I don't know if the "~/my.html" works; maybe you should do os.expanduser('~/my.html') instead.)

You could even do

def call_7000(*args, **kwargs):
    import socket
    import itertools
    s = socket.create_connection(('localhost', 7000))
    items = itertools.chain(" ".join("-%s %s" % (k, v) for k, v in kwargs), a)
    s.write(" ".join(str(i) for i in items)
    s.close()

and call it with

call_7000("/tmp/my1.pdf", s="letter", T="24mm", R="24mm", B="0mm", g="~/my.html")

if the ordering of the options is not relevant.

Upvotes: 1

Related Questions