LINUX.ORG.RU

Проблема с subprocess. Не получается реализовать создание конвейеров внутри одной команды.

 


0

2
aA = subprocess.Popen(
    ['ifconfig', 'wls1', '|', 'grep', '-o', '"..:..:..:..:..:..:.."'], 
    stdout=subprocess.PIPE
)
aA1 = aA.stdout.read()
aA2 = str(aA1) 
print(aA1)
__
Result: 

|: Unknown host
ifconfig: `--help' gives usage information.
b''

Как можно реализовать в subprocess эту shell-команду и получить вывод?

ifconfig wls1 | grep -o "..:..:..:..:..:.."


subprocess.Popen('ifconfig wls1 | grep -o "..:..:..:..:..:..«', shell=True)

Но это не рекомендуется делать.

Можно как-то так:

grep_proc = subprocess.Popen(["grep", "rabbitmq"],
                             stdin=subprocess.PIPE, 
                             stdout=subprocess.PIPE)
subprocess.Popen(["ps", "aux"], stdout=grep_proc.stdin)
out, err = grep_proc.communicate()
pawnhearts ★★★★★
()
Последнее исправление: pawnhearts (всего исправлений: 1)
Ответ на: комментарий от pawnhearts

2 идея хороша, спасибо.

Кстати, есть ли смысл использовать shell=True, если это для личного пользования? Т.е. никто извне не сможет иметь доступ.

kramh
() автор топика
Ответ на: комментарий от kramh

Т.е. никто извне не сможет иметь доступ.

Причем тут это? Дело в том, что всякие эти «|» разбирает интерпретатор шелл и создает конвеер. Если ты просто запускаешь программу через spawn* или там exec* ты можешь только передать путь к программе и аргументы, всякие «|» работать не будут.

а Popen(.., shell=True) это, в общем, аналог subprocess.Popen(['/bin/sh', '-c', 'ps aux|grep python'])

И sh уже разбирает эту строку.

P.S. во многих книжках по программированию под unix/linux в качестве примера разбирается написание примитивного шелла который будет в т.ч. разбирать конвееры и строить их перенаправляя вывод из одной программы в другую.

P.P.S. второй вариант может порождать зомби процессы при определенных условиях. У варианта с запуском через шелл свои недостатки - например тебе надо будет думать об экранировании параметров т.е. Popen(['cat','file with space.txt']) будет работать, а при shell=True надо будет имя файла брать в кавычки или экранировать пробелы. Потом ты получишь pid шелла, а не команд, которых в нем выполняешь.

pawnhearts ★★★★★
()
Последнее исправление: pawnhearts (всего исправлений: 2)

Программист на баше даже не питоне напишет на баше!

А если серьёзно, то с учётом наличия кода на питоне, grep тебе точно не нужен. Используй питоновские средства для обработки текста.

В зависимости от конкретной задачи, может не понадобится даже ifconfig (а значит и subprocess вообще).

Кстати, вывод ip парсить проще, ИМХО.

Deleted
()
Ответ на: комментарий от pawnhearts

Есть куча либ (костылей) для питона чтобы не вызывать ifconfig и не читать sys.

true_admin ★★★★★
()

python3 -c 'print(open(«/sys/class/net/wls1/address»).read().strip())'

A1
()

Можно, пожалуйста, пример такого кода? Например, как вывывести MAC чисто на питоне.

Или что-то почитать на эту тему? Я просто даже не могу представить, как можно взаимодействовать с системой без баша.

kramh
() автор топика
Ответ на: комментарий от kramh

Кроме очевидного open, конечно.

Why not?

def get_mac_address(ifname):
    return open('/sys/class/net/%s/address' % ifname).read()

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от kramh

Я просто даже не могу представить, как можно взаимодействовать с системой без баша.

Запускать утилиты можно и без баша. Даже нужно.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.