2009-04-01 63 views
33

Làm cách nào tôi có thể gọi chương trình bên ngoài bằng tập lệnh python và truy xuất mã đầu ra và trả về?Làm thế nào để gọi một chương trình bên ngoài trong python và lấy đầu ra và trả về mã?

+2

Có một số câu hỏi và câu trả lời hiện có về SO sẽ giúp bạn: http://stackoverflow.com/questions/89228/how-to-call-external-command-in-python –

+0

Có thể trùng lặp của [Gọi một lệnh bên ngoài bằng Python] (http://stackoverflow.com/questions/89228/calling-an-external-command-in-python) –

Trả lời

45

Nhìn vào subprocess mô-đun: một ví dụ đơn giản sau ...

from subprocess import Popen, PIPE 

process = Popen(["ls", "-la", "."], stdout=PIPE) 
(output, err) = process.communicate() 
exit_code = process.wait() 
+10

Tôi đã chỉnh sửa câu trả lời ở trên để phản ánh đề xuất của Ambroz trong trường hợp ai đó làm không đọc nhận xét và sử dụng mã không chính xác trước đó. –

+0

nếu điều này không vì lý do nào đó, bạn có thể muốn thêm shell = True vào các tham số (khi ở trong cửa sổ?) – ntg

+0

Dường như [giải pháp trên] (https://stackoverflow.com/a/707001/1321680) có thể được thay thế bằng lệnh gọi đơn giản ['subprocess.run()'] (https://docs.python.org/dev/library/subprocess.html#subprocess.run) (Python> = 3.5 là bắt buộc). –

13

Tiếp theo bình luận trước Ambrož Bizjak của, đây là một giải pháp mà làm việc cho tôi:

import shlex 
from subprocess import Popen, PIPE 

cmd = "..." 
process = Popen(shlex.split(cmd), stdout=PIPE) 
process.communicate() 
exit_code = process.wait() 
+3

Đây là câu trả lời hay nhất. – dotancohen

+3

Tôi có một bài viết tương tự [ở đây] (https://stackoverflow.com/questions/1996518/retrieving-the-output-of-subprocess-call/21000308#21000308) cho thấy làm thế nào để có được ba điều từ một quá trình: exitcode , stdout, stderr. – Jabba

2

Sau khi một số nghiên cứu, tôi có đoạn mã sau đó hoạt động rất tốt đối với tôi. Về cơ bản nó in cả stdout và stderr trong thời gian thực. Hy vọng nó sẽ giúp người khác cần nó.

stdout_result = 1 
stderr_result = 1 


def stdout_thread(pipe): 
    global stdout_result 
    while True: 
     out = pipe.stdout.read(1) 
     stdout_result = pipe.poll() 
     if out == '' and stdout_result is not None: 
      break 

     if out != '': 
      sys.stdout.write(out) 
      sys.stdout.flush() 


def stderr_thread(pipe): 
    global stderr_result 
    while True: 
     err = pipe.stderr.read(1) 
     stderr_result = pipe.poll() 
     if err == '' and stderr_result is not None: 
      break 

     if err != '': 
      sys.stdout.write(err) 
      sys.stdout.flush() 


def exec_command(command, cwd=None): 
    if cwd is not None: 
     print '[' + ' '.join(command) + '] in ' + cwd 
    else: 
     print '[' + ' '.join(command) + ']' 

    p = subprocess.Popen(
     command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd 
    ) 

    out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,)) 
    err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,)) 

    err_thread.start() 
    out_thread.start() 

    out_thread.join() 
    err_thread.join() 

    return stdout_result + stderr_result 
3

tôi đã phát triển một chút thư viện (py-execute) cho phép bạn thực hiện các chương trình bên ngoài, lấy đầu ra và retcode và, cùng một lúc nhận được kết quả trong giao diện điều khiển trong thời gian thực:

>>> from py_execute.process_executor import execute 
>>> ret = execute('echo "Hello"') 
Hello 
>>> ret 
(0, 'Hello\n') 

Bạn có thể tránh in ấn để an ủi đi qua một user_io giả:

>>> from mock import Mock 
>>> execute('echo "Hello"', ui=Mock()) 
(0, 'Hello\n') 

tôi đã viết nó vì với đồng bằng Popen (Trong Python 2.7) tôi đã gặp khó khăn trong thực hiện comm ands với đầu ra dài

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