2012-01-23 30 views
10

Tôi đã viết một kịch bản python đơn giản cho ứng dụng của tôi và xác định trước một số lệnh nhanh chóng thích làm, vvLàm cách nào để nhận dữ liệu stdout của tiến trình con không đồng bộ?

Tôi đã viết một chức năng để chạy các lệnh hệ thống (Linux):

def runCommand(commandLine): 
    print('############## Running command: ' + commandLine) 
    p = subprocess.Popen(commandLine, shell = True, stdout = subprocess.PIPE) 
    print (p.stdout.read().decode('utf-8')) 

Tất cả mọi thứ hoạt động tốt, ngoại trừ một vài điều:

  • Tôi đang sử dụng cmake và đầu ra của nó được tô màu. Bất kỳ cơ hội để tiết kiệm màu sắc trong đầu ra?

  • Tôi có thể xem kết quả sau khi quá trình kết thúc. Ví dụ: làm cho chạy trong một thời gian dài nhưng tôi chỉ có thể xem kết quả sau khi biên dịch đầy đủ. Làm thế nào để làm điều đó một cách không đồng bộ?

Trả lời

12

Tôi không chắc chắn về màu sắc, nhưng đây là cách để thăm dò ý kiến ​​stdout một dòng của tiến trình con tại một thời điểm:

import subprocess 
proc = subprocess.Popen('cmake', shell=True, stdout=subprocess.PIPE) 
while proc.poll() is None: 
    output = proc.stdout.readline() 
    print output 

Đừng quên để đọc từ stderr là tốt, như tôi chắc chắn rằng cmake sẽ phát ra thông tin ở đó.

+0

OK, cảm ơn. Nó hoạt động. – Ockonal

2

Về làm thế nào để có được đầu ra của quá trình của bạn trước khi nó kết thúc, chúng ta có thể làm điều đó thay thế:

p.stdout.read 

với:

for line in p.stdout: 

Về làm thế nào để tiết kiệm màu đầu ra, không có gì đặc biệt về điều đó. Ví dụ, nếu đầu ra hàng được lưu vào một tập tin, sau đó thời gian tiếp theo cat <logfile> được thực hiện bàn điều khiển sẽ giải thích các trình tự thoát và hiển thị màu sắc như mong đợi.

+0

với 'readline()' Tôi có một số liên tiếp thay vì văn bản, có gì sai? – Ockonal

+1

@Ockonal Trên thực tế nếu bạn sử dụng vòng lặp for, không cần sử dụng 'readline'. Bạn có thể tìm thấy ví dụ về cả hai chiến lược [ở đây] (http://stackoverflow.com/q/2804543/183066). – jcollado

+0

Thực tế 'cho dòng trong p.stdout' không tốt trong Python 2 theo http://stackoverflow.com/questions/2804543/read-subprocess-stdout-line-by-line#comment11236752_2813530 –

0

Để làm ra async làm điều gì đó như: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554

Không chắc chắn nếu bạn có thể nắm bắt đầu ra màu. Nếu bạn có thể nhận được mã màu thoát, bạn có thể.

+0

Nếu chúng tôi nhận được mã màu, thiết bị đầu cuối sẽ dịch chúng. Vấn đề là mặc dù, hầu hết các ứng dụng phân biệt giữa đang được gắn vào một thiết bị đầu cuối hoặc được đường ống vào một ứng dụng khác. Cách duy nhất để thuyết phục các ứng dụng này vẫn tạo ra mã màu bằng cách giả mạo rằng ứng dụng nhận (trong trường hợp này là quá trình python của chúng ta) thực ra là một tty chứ không phải là một đường ống. Một nhiệm vụ dễ dàng hơn nhiều so với thực hiện ... –

4

Bạn không nhận được màu vì cmake phát hiện xem thiết bị đầu cuối của nó có phải là thiết bị đầu cuối không, nếu nó không có màu đầu ra của riêng nó. Một số chương trình cung cấp cho bạn một tùy chọn để ép màu đầu ra. Thật không may cmake không, vì vậy bạn đang ở ngoài may mắn ở đó. Trừ khi bạn muốn tự vá cmake.

Rất nhiều chương trình làm việc này, ví dụ như grep:

# grep test test.txt 
test 
^ 
| 
|------- this word is red 

Bây giờ ống nó để mèo:

# grep test test.txt | cat 
test 
^ 
| 
|------- no longer red 

grep tùy chọn --color=always để buộc màu:

# grep test test.txt --color=always | cat 
test 
^ 
| 
|------- red again 
-1

Worth lưu ý đây là việc sử dụng lệnh script như một thuật ngữ giả l và được phát hiện như một tty thay vì chuyển hướng (ống) mô tả tập tin, xem: bash command preserve color when piping

trình như một nét duyên dáng ...

Theo ví dụ trong câu hỏi đơn giản để thực hiện scriptcmake:

import subprocess 
proc = subprocess.Popen('script cmake', shell=True, stdout=subprocess.PIPE) 
while proc.poll() is None: 
    output = proc.stdout.readline() 
    print output 

Thủ thuật này cmake nghĩ rằng nó đang được thực hiện từ một thiết bị đầu cuối và sẽ sản xuất kẹo ANSI mà bạn đang theo dõi.

nJoy!

Các vấn đề liên quan