2011-09-19 6 views
11

Próbuję odejść od os.popen do podprocesu.popen zgodnie z zaleceniami podręcznika użytkownika. Jedyny kłopot, jaki mam, to nie mogę znaleźć sposobu na wykonanie funkcji readlines().Python subprocess readlines()?

Więc użyłem, aby móc zrobić

list = os.popen('ls -l').readlines() 

Ale nie mogę zrobić

list = subprocess.Popen(['ls','-l']).readlines() 
+1

wolałbym zrobić 'list = subprocess.call ([ 'ls', '- L']) readlines() ' – jdborg

+2

To źle -. 'Call' zwraca tylko returnCode, a nie wyjście. – agf

+0

http://stackoverflow.com/questions/2924310/whats-a-good-equivalent-to-pythons-subprocess-check-call-that-returns-the-conte – jfs

Odpowiedz

23

Z subprocess.Popen, użyj communicate do odczytu i zapisu danych:

out, err = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE).communicate() 

Następnie zawsze możesz podzielić ciąg znaków z procesów "stdout z splitlines().

out = out.splitlines() 
+0

Pomyślałem, że to miało być "ładną nową drogą" "robienia tego. Dzięki za odpowiedź, ustawię ją, gdy upłynie limit czasu. Mógłbym trzymać się popena. – jdborg

+3

Problem z 'komunikacją' polega na tym, że dostajesz wszystkie dane wyjściowe na raz, co w przypadku nierekurencyjnego' ls' nie jest prawdopodobnie problemem. Używając elementu 'stdout', możesz czytać line-by-line (pomyśl' find'). –

25
ls = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE) 
out = ls.stdout.readlines() 

lub, jeśli chcesz przeczytać linia po linii (może inny proces jest bardziej intensywny niż ls):

for ln in ls.stdout: 
    # whatever 
+1

To podejście jest lepsze od akceptowanej odpowiedzi, ponieważ pozwala na odczytanie wyniku w procesie podrzędnym. – Hoons

3
list = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0].splitlines() 

prosto z help(subprocess)

+0

To nie jest lista linii, to pojedynczy wieloliniowy ciąg. – agf

+0

Dobra sprawa, naprawiona – Kimvais

8

Making a system call that returns the stdout output as a string:

lines = subprocess.check_output(['ls', '-l']).splitlines() 
+0

Miło, myślę, że nie jest powszechnie znana, ponieważ jest to tylko Python 2.7+. – agf

+0

@agf: skorzystaj z linku, jest adaptacja dla starszych wersji Pythona. – jfs

+0

Wiem, już śledziłem oba linki, które opublikowałeś (i wznowiłeś każdy post). Byłem po prostu zaskoczony, że nie wiedziałem o tej funkcji wygody, dopóki nie zobaczyłem, że wynosi ona 2.7+. – agf

3

Bardziej szczegółowy sposób użycia podprocesu.

 # Set the command 
     command = "ls -l" 

     # Setup the module object 
     proc = subprocess.Popen(command, 
          shell=True, 
          stdin=subprocess.PIPE, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

     # Communicate the command 
     stdout_value,stderr_value = proc.communicate() 

     # Once you have a valid response, split the return output  
     if stdout_value: 
      stdout_value = stdout_value.split() 
Powiązane problemy