gEr
gEr

Reputation: 215

Getting output of system commands that use pipes (Python)

I'm trying to generate a random string using this command:

strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n';

Works fine, but when I try to do subprocess.call(cmd,shell=True) it just gets stuck on the strings /dev/urandom command and spams my screen with grep: writing output: Broken pipe

What's causing this and how do I fix it?

Upvotes: 4

Views: 280

Answers (2)

Kimvais
Kimvais

Reputation: 39548

No need for subprocess, observe:

>>> import base64
>>> r = open("/dev/urandom","r")
>>> base64.encodestring(r.read(22))[:30]
'3Ttlx6TT3siM8h+zKm+Q6lH1k+dTcg'
>>> r.close()

Also, stringsing and then greping alphanumeric characters from /dev/urandom is hugely inefficient and wastes a whole lot of randomness. On my desktop PC, the above python takes less than 10 ms to executed from bash, your strings ... oneliner takes 300-400...

For a pure python solution that works also on systems without /dev/urandom - and gives only alphanumeric characters (if you really don't want + or /):

import string
import random
''.join([random.choice(string.printable[:62]) for i in range(30)])

Upvotes: 5

mdeous
mdeous

Reputation: 18029

First of all, for what you're doing, it should be better to generate the string using python directly.

Anyway, when using subprocess, the correct way to pipe data from a process to another is by redirecting stdout and/or stderr to a subprocess.PIPE, and feed the new process' stdin with the previous process' stdout.

Upvotes: 0

Related Questions