`Subprocess` komutunu borularla kullanma


246

Ben kullanmak istiyorum subprocess.check_output()ile ps -A | grep 'process_name'. Çeşitli çözümler denedim ama şimdiye kadar hiçbir şey işe yaramadı. Birisi bana nasıl yapılacağını söyleyebilir mi?



4
orada psutilbir taşınabilir şekilde süreç bilgi almak için izin verir.
jfs

Yanıtlar:


439

subprocessModülle birlikte bir boru kullanmak için geçmeniz gerekir shell=True.

Ancak, bu çeşitli nedenlerle gerçekten tavsiye edilmez, en azından güvenlik değildir. Bunun yerine, psve grepişlemlerini ayrı ayrı oluşturun ve çıktıyı birinden diğerine geçirin, şöyle:

ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()

Bununla birlikte, özel durumunuzda, basit çözüm çağrı yapmak subprocess.check_output(('ps', '-A'))ve sonra str.findçıkıştır.


81
Kullanmamak için çıkışı / girişi ayırmak için +1shell=True
Nicolas

5
Unutmayın, hata subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1sadece grep tarafından hiçbir şey bulunmadığı anlamına gelir, bu yüzden normal davranıştır.
Serge

2
Çıktıya ps.wait()zaten sahip olduğumuzda neden ihtiyacımız var? ps.wait.__doc__çocuğun sona ermesini bekler, ancak çocuğun içeriği zaten outputdeğişkene yerleştirilmiş gibi görünür
Papouche Guinslyzinho

3
@MakisH Baktığınız string.find, lehine reddedilen str.find(yani nesneler findüzerindeki yöntem str).
Taymon

4
not: greperken ölürse; psOS boru arabelleğini doldurmak için yeterli çıktı üretiyorsa süresiz olarak askıda kalabilir (çünkü ps.stdout.close()ana öğeyi aramadıysanız). Bundan kaçınmak için başlangıç ​​sırasını değiştirin
jfs

54

Veya alt işlem nesnelerinde iletişim yöntemini her zaman kullanabilirsiniz.

cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)

Communications yöntemi, standart çıktının ve standart hatanın bir demetini döndürür.


3
Bence kullanmak communicatedaha iyidir wait. Orada böyle uyarı:. "Bu stdout'u = BORU ve / veya stderr'yi = BORU ve çocuk işlemini kullanırken kilitlenmeye bir boruya yeterli çıktı üretir OS boru tampon bekliyor engeller daha fazla veri kabul etmek öyle Kullanım iletişim () için bundan kaçının. "
Paolo

2
Paolo'nun yukarıdaki açıklamasını netleştirmek için, uyarı iletişim için değil, beklemek içindir - yani iletişimin daha iyi olduğunu söylemesinin nedeni budur.
EnemyBagJones

23

Alt süreç kullanarak bir boru hattı kurma hakkındaki belgelere bakın: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline

Aşağıdaki kod örneğini test etmedim ama kabaca ne istediğinizi olmalı:

query = "process_name"
ps_process = Popen(["ps", "-A"], stdout=PIPE)
grep_process = Popen(["grep", query], stdin=ps_process.stdout, stdout=PIPE)
ps_process.stdout.close()  # Allow ps_process to receive a SIGPIPE if grep_process exits.
output = grep_process.communicate()[0]

2
Bunu kontrol edemedikten sonra, Taymon'un etrafı dolaşmadan çalışan bir şey için aşağıdaki cevaba bakınız
Alvin

2
subprocess.check_output, Python
2.6.9'da

6

JKALAVIS çözümü iyidir, ancak SHELL = TRUE yerine shlex kullanmak için bir iyileştirme ekleyeceğim. aşağıda im grepping out Sorgu zamanları

#!/bin/python
import subprocess
import shlex

cmd = "dig @8.8.4.4 +notcp www.google.com|grep 'Query'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)

1
Neden kabuk üzerinde shellx?
AFP_555

2
shlex burada nerede kullanılır?
3lokh

4

Ayrıca, 'pgrep'komut yerine'ps -A | grep 'process_name'


2
süreç kimliği almak istiyorsanız, belli ki
Shooe


-1

Python 3.5 Sonrası şunları da kullanabilirsiniz:

    import subprocess

    f = open('test.txt', 'w')
    process = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, universal_newlines=True)
    f.write(process.stdout)
    f.close()

Komutun yürütülmesi engelleniyor ve çıktı process.stdout içinde olacak .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.