Получение вывода системных команд, использующих каналы (Python) - PullRequest
4 голосов
/ 17 августа 2011

Я пытаюсь сгенерировать случайную строку с помощью этой команды:

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

Работает нормально, но когда я пытаюсь сделать subprocess.call(cmd,shell=True), он просто застревает в команде strings / dev / urandom и спамит мой экран с помощью grep: writing output: Broken pipe

Что вызывает это и как я могу это исправить?

Ответы [ 2 ]

5 голосов
/ 17 августа 2011

Нет необходимости в подпроцессе, соблюдайте:

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

Кроме того, strings ввод, а затем grep извлечение буквенно-цифровых символов из /dev/urandom является чрезвычайно неэффективным и тратит много случайности. На моем настольном ПК приведенный выше питон выполняется менее чем за 10 мс из bash, ваш strings ... oneliner занимает 300-400 ...

Для чисто Python-решения, которое работает также в системах без /dev/urandom - и дает только буквенно-цифровые символы (если вы действительно не хотите + или /):

import string
import random
''.join([random.choice(string.printable[:62]) for i in range(30)])
0 голосов
/ 17 августа 2011

Прежде всего, для того, что вы делаете, было бы лучше сгенерировать строку, используя непосредственно python.

В любом случае, при использовании subprocess, правильный способ передачи данных из процесса вдругой - путем перенаправления stdout и / или stderr на subprocess.PIPE и подачи нового процесса 'stdin с предыдущим процессом' stdout.

...