Hướng dẫn python subprocess get output - quy trình con python lấy đầu ra

Nội dung chính ShowShow

  • Subprocess trong Python là gì
  • Hàm subprocess.run() và xử lý đồng bộ trong Python
  • Cú pháp hàm subprocess.run() trong python
  • Sử dụng hàm subprocess.run() để gọi các lệnh CMD từ Python
  • Sử dụng hàm subprocess.run() để gọi các ứng dụng khác từ Python
  • Sử dụng hàm subprocess.run() để gọi chương trình python từ một tệp khác
  • Sử dụng hàm subprocess.run() để xử lý đồng bộ trong Python
  • Class subprocess.Popen() và xử lý bất đồng bộ trong Python
  • Sử dụng class subprocess.Popen() để xử lý bất đồng bộ trong Python
  • Sử dụng các phương thức trong class subprocess.Popen()
  • Nén file Zip bằng Python
  • Sự khác nhau giữa subprocess.Popen() và subprocess.run()
  • Tổng kết

Hướng dẫn sử dụng module subprocess trong Python để gọi một lệnh hoặc ứng dụng khác từ Python. Bạn cũng sẽ học được cách dùng subprocess.run() và subprocess.Popen() trong module subprocess để xử lý đồng bộ và bất đồng bộ trong Python sau bài học này.subprocess trong Python để gọi một lệnh hoặc ứng dụng khác từ Python. Bạn cũng sẽ học được cách dùng subprocess.run() và subprocess.Popen() trong module subprocess để xử lý đồng bộ và bất đồng bộ trong Python sau bài học này.

Subprocess trong Python là gì

Subprocess trong Python là một mô-đun giúp chạy lệnh hoặc các ứng dụng khác từ chương trình Python và thu về kết quả thực thi. Subprocess còn được gọi là mô-đun quy trình con và được bao gồm trong thư viện chuẩn Python. là một mô-đun giúp chạy lệnh hoặc các ứng dụng khác từ chương trình Python và thu về kết quả thực thi. Subprocess còn được gọi là mô-đun quy trình con và được bao gồm trong thư viện chuẩn Python.

Hướng dẫn python subprocess get output - quy trình con python lấy đầu ra

Subprocess có thể gọi một lệnh hoặc một ứng dụng bên ngoài từ bên trong tập lệnh python. Ví dụ với Subprocess chúng ta có thể:

  • Thực thi các lệnh CMD từ Python
  • Gọi chương trình nén file 7z từ Python
  • Chạy các lệnh của AWS CLI từ Python
  • Chạy các lệnh deploy web từ Python
  • Thực thi các lệnh Shell với Python

Ở trong các phiên bản Python cũ, chúng ta sử dụng subprocess trong Python với rất nhiều hàm như là call(), check_call(), check_output() hay Popen(). Tuy nhiên kể từ Python 3.5 trở đi, subprocess trong Python đã được làm lại và chúng ta chỉ cần sử dụng một hàm chung cho tất cả các trường hợp là subprocess.run(), và một class cung cấp nhiều lựa chọn linh hoạt hơn dành cho các nhà phát triển là subprocess.Popen() mà thôi.

Hàm subprocess.run() và xử lý đồng bộ trong Python

Hàm subprocess.run() giúp chúng ta tạo ra một xử lý đồng bộ khi gọi một lệnh hoặc ứng dụng khác từ Python. Điều đó có nghĩa, khi lệnh hoặc ứng dụng khác đã được gọi, chúng ta phải chờ cho nó kết thúc rồi mới có thể thực thi các lệnh python tiếp theo trong chương trình. Chúng ta sẽ cùng làm rõ xử lý đồng bộ này ở phần dưới đây.xử lý đồng bộ khi gọi một lệnh hoặc ứng dụng khác từ Python. Điều đó có nghĩa, khi lệnh hoặc ứng dụng khác đã được gọi, chúng ta phải chờ cho nó kết thúc rồi mới có thể thực thi các lệnh python tiếp theo trong chương trình. Chúng ta sẽ cùng làm rõ xử lý đồng bộ này ở phần dưới đây.

Cú pháp hàm subprocess.run() trong python

Sử dụng hàm subprocess.run() để gọi các lệnh CMD từ Python

Sử dụng hàm subprocess.run() để gọi các ứng dụng khác từ Python
subprocess.run ([“lệnh chạy”], tùy chọn)

Sử dụng hàm subprocess.run() để gọi chương trình python từ một tệp khác

  • Sử dụng hàm subprocess.run() để xử lý đồng bộ trong Python
  • Class subprocess.Popen() và xử lý bất đồng bộ trong Python

Sử dụng class subprocess.Popen() để xử lý bất đồng bộ trong Python

Sử dụng các phương thức trong class subprocess.Popen()Nén file Zip bằng PythonSự khác nhau giữa subprocess.Popen() và subprocess.run()
Tổng kếtHướng dẫn sử dụng module subprocess trong Python để gọi một lệnh hoặc ứng dụng khác từ Python. Bạn cũng sẽ học được cách dùng subprocess.run() và subprocess.Popen() trong module subprocess để xử lý đồng bộ và bất đồng bộ trong Python sau bài học này.Subprocess trong Python là một mô-đun giúp chạy lệnh hoặc các ứng dụng khác từ chương trình Python và thu về kết quả thực thi. Subprocess còn được gọi là mô-đun quy trình con và được bao gồm trong thư viện chuẩn Python.
Subprocess có thể gọi một lệnh hoặc một ứng dụng bên ngoài từ bên trong tập lệnh python. Ví dụ với Subprocess chúng ta có thể:Thực thi các lệnh CMD từ PythonGọi chương trình nén file 7z từ Python
Chạy các lệnh của AWS CLI từ PythonChạy các lệnh deploy web từ PythonThực thi các lệnh Shell với Python
Ở trong các phiên bản Python cũ, chúng ta sử dụng subprocess trong Python với rất nhiều hàm như là call(), check_call(), check_output() hay Popen(). Tuy nhiên kể từ Python 3.5 trở đi, subprocess trong Python đã được làm lại và chúng ta chỉ cần sử dụng một hàm chung cho tất cả các trường hợp là subprocess.run(), và một class cung cấp nhiều lựa chọn linh hoạt hơn dành cho các nhà phát triển là subprocess.Popen() mà thôi.Hàm subprocess.run() giúp chúng ta tạo ra một xử lý đồng bộ khi gọi một lệnh hoặc ứng dụng khác từ Python. Điều đó có nghĩa, khi lệnh hoặc ứng dụng khác đã được gọi, chúng ta phải chờ cho nó kết thúc rồi mới có thể thực thi các lệnh python tiếp theo trong chương trình. Chúng ta sẽ cùng làm rõ xử lý đồng bộ này ở phần dưới đây.Chúng ta sử dụng hàm subprocess.run() với cú pháp sau đây:
import subprocesssubprocess.run ([“lệnh chạy”], tùy chọn)Trong đó:
(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
5 là lệnh gọi ứng dụng hoặc câu lệnh khác từ python. Ví dụ như lệnh gọi chương trình nén file 7z từ Python sẽ là “C:/Program Files/7-Zip/7z.exe a test.7z”, hoặc là lệnh CMD kiểm tra list file là dir trong windows hoặc ls trong Linux chẳng hạn.
(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
6 là các chỉ định bạn có thể thêm khi sử dụng subprocess.
Các tùy chọn phổ biến có thể chỉ định khi sử dụng subprocess trong python như bảng dưới đây:Tùy chọn

Chức năng

Ví dụ

Sử dụng hàm subprocess.run() để gọi các lệnh CMD từ Python

stdin

  |test
  |--user
  |  |--username
  |  |--sample.py
  |  |--test.py

Đầu vào tiêu chuẩn. Sử dụng khi cần lấy dữ liệu đầu vào

(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username

stdin = subprocess.DEVNULL

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))

stdout

print(result.returncode) 
print(result.args)

Đầu ra tiêu chuẩn. Sử dụng khi cần lấy kết quả thực thi lệnh

Sử dụng hàm subprocess.run() để gọi các ứng dụng khác từ Python

stdout = subprocess.PIPE

stderr

import subprocess
cmd = "D:/test/user/bang-cuu-chuong/sample.exe"
result = subprocess.run(cmd, shell=True)

Kết quả:

Không chỉ với ứng dụng mà chúng ta tự đóng gói, bạn cũng có thể gọi tất cả các ứng dụng khác chạy trên máy tính từ Python. Ví dụ, bạn có thể gọi chương trình nén file 7z từ python với cách viết sau đây:

import subprocess
cmd = ["C:/Program Files/7-Zip/7z.exe", 'a', 'Test.7z', 'Test', '-mx9']
result = subprocess.run(cmd, shell=True)

Hoặc là đơn giản, bạn có thể mở một file Excel từ python với cách viết như sau:

import subprocess
cmd = "sample.xlsx",
result = subprocess.run(cmd, shell=True)

Sử dụng hàm subprocess.run() để gọi chương trình python từ một tệp khác

Bạn cũng có thể gọi chương trình trong file python

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 chứa mã nguồn của ứng dụng in ra bảng cửu chương trong Python ở trên bằng một tệp lệnh python khác.

Ví dụ, chúng ta có mã nguồn của ứng dụng in ra bảng cửu chương trong Python như sau:

for i in range(9):
i += 1
print("2 * " + str(i) + " = " + str(2*i))

Chúng ta sẽ gọi chạy chương trình viết trong file

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 từ tệp
import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
2 bằng subprocess.run() với nội dung như sau:

import subprocess
cmd = 'python', "D:/test/user/sample.py"
result = subprocess.run(cmd, shell=True)

Sử dụng hàm subprocess.run() để xử lý đồng bộ trong Python

Xử lý đồng bộ trong Python có ý nghĩa, các câu lệnh sẽ được thực hiện theo thứ tự, và câu lệnh phía trước phải kết thúc thì câu lệnh sau đó mới có thể thực hiện.Bằng cách sử dụng subprocess.run(), chúng ta có thể xử lý đồng bộ trong Python như ví dụ sau. Chúng ta sẽ gọi lại file

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 ở trên với tệp python có mã nguồn sau đây:
Bằng cách sử dụng subprocess.run(), chúng ta có thể xử lý đồng bộ trong Python như ví dụ sau. Chúng ta sẽ gọi lại file
import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 ở trên với tệp python có mã nguồn sau đây:

import subprocess
cmd = "sample.xlsx",
result = subprocess.run(cmd, shell=True)
print("end")

Mã nguồn trên gồm 2 phần là phần gọi quy trình con từ file

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 và phần chạy lệnh in ra màn hình. Do subprocess.run() là xử lý đồng bộ nên quy trình con trong
import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 sẽ được thực thi, và sau khi quy trình con này kết thúc thì lệnh print mới được xử lý như sau:

Class subprocess.Popen() và xử lý bất đồng bộ trong Python

Class subprocess.Popen() giúp chúng ta tạo ra một xử lý bất đồng bộ khi gọi một lệnh hoặc ứng dụng khác từ Python. Điều đó có nghĩa, sau khi lệnh hoặc ứng dụng khác đã được gọi, chúng ta vẫn có thể xử lý các lệnh python khác, hoặc xử lý kết quả tạm thời của ứng dụng trong khi ứng dụng được gọi vẫn đang chạy.xử lý bất đồng bộ khi gọi một lệnh hoặc ứng dụng khác từ Python. Điều đó có nghĩa, sau khi lệnh hoặc ứng dụng khác đã được gọi, chúng ta vẫn có thể xử lý các lệnh python khác, hoặc xử lý kết quả tạm thời của ứng dụng trong khi ứng dụng được gọi vẫn đang chạy.

Cú pháp của Class subprocess.Popen() cũng tương tự như hàm subprocess.run(), và cách sử dụng class subprocess.Popen() để gọi các lệnh CMD từ Python, gọi các ứng dụng khác từ Python hay gọi chương trình python từ một tệp khác cũng tương tự như với hàm subprocess.run().

import subprocessresult = subprocess.Popen ([“lệnh chạy”], tùy chọn)
result = subprocess.Popen ([“lệnh chạy”], tùy chọn)

Sử dụng class subprocess.Popen() để xử lý bất đồng bộ trong Python

Để làm rõ xử lý bất đồng bộ trong python bằng subprocess.Popen(), chúng ta sẽ gọi lại chương trình ghi trong file

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 trong các ví dụ ở trên bằng subprocess.Popen() được ghi trong tập lệnh python có nội dung sau đây:

(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
0

Khác với subprocess.run() sẽ kết thúc thực thi chương trình trong

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 rồi mới chạy lệnh print thì do trong subprocess.Popen() là xử lý bất đồng bộ nên quy trình con trong file sample.py sẽ được xử lý đồng thời với lệnh
import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
8, và do lệnh print có tốc độ xử lý nhanh hơn nên đã in trước kết quả ra màn hình như sau:

Bạn có thể thấy rõ dòng

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
9 được in ra trước các kết quả của bảng cửu chương rồi phải không nào? Hãy so sánh với kết quả của xử lý đồng bộ trong python bằng hàm subprocess.run() ở trên :

Sử dụng các phương thức trong class subprocess.Popen()

Mặc dù cú pháp sử dụng subprocess.Popen() cũng tương tự như với subprocess.run(), tuy nhiên bạn cần chú ý rằng kết quả trả về của hai phương pháp này là hoàn toàn khác nhau.

Khác với hàm subprocess.run() trả về một instance của class CompletedProcess thì class subprocess.Popen() sẽ trả về một hàm tạo (constructor) với các phương thức xử lý linh hoạt kèm theo. Chúng ta không những có thể sử dụng các thuộc tính như returncode, stdout, args của hàm subprocess.run() mà còn có thể dùng thêm các phương thức như Popen.poll(),Popen.terminate(), Popen.communicate() hay Popen.kill().

Do đặc tính này mà subprocess.Popen() sẽ cung cấp nhiều lựa chọn hơn để xử lý lệnh cho các nhà phát triển, ví dụ như là kiểm tra quá trình chạy của quy trình con, dừng quy trình con giữa chừng, chờ quy trình con chạy hết và gán kết quả vào một biến chẳng hạn.

Ví dụ, chúng ta có thể sử dụng phương thức communicate() để chờ cho quy trình con chạy xong và nhận dữ liệu đầu vào và kết quả đầu ra xong xuôi, rồi mới tiến hành chạy các lệnh tiếp theo trong chương trình chính như sau:

(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
1

Kết quả, chương trình trong

import subprocess
result = subprocess.run("dir", shell=True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(result.stdout.decode("cp932"))
0 thực thi xong rồi lệnh print mới được thực thi , và dữ liệu đầu vào và kết quả đầu ra được gán vào biến result và in ra màn hình tương tự như với hàm subprocess.run() như sau:

Bạn có thể tìm hiểu cách sử dụng chi tiết các phương thức của class subprocess.Popen() tại https://docs.python.org/

Nén file Zip bằng Python

Một ứng dụng cụ thể khác của phương thức communicate() trong subprocess.Popen(), đó chính là gọi chương trình nén file 7z và tạo file zip sử dụng python. Trong hệ điều hành Windows, nếu bạn biết vị trí đã cài đặt phần mềm 7z trong máy tính của mình, giả sử là “C:/Program Files/7-Zip/7z.exe”, thì bạn có thể sử dụng tới hàm nén file Zip bằng Python sau đây để tự động nén file bằng python như sau:

(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
2

Trong đó,

print(result.returncode) 
print(result.args)
1 là đường dẫn của file nén tạo ra, và
print(result.returncode) 
print(result.args)
2 là đường dẫn của thư mục cần nén.

Ví dụ, bạn có thể gọi hàm trên để nén thư mục sample và tạo ra file nén sample.zip như sau:

(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
3

Bằng cách tương tự thì bạn cũng có thể gọi phần mềm nén file 7z trong hệ điều hành Ubuntu, sau khi đã cài đặt nó trong máy tính, với hàm nén file zip bằng python như sau:

(base) D:\test\user>dir

Volume in drive D is OS
Directory of D:\test\user

2021/06/16 13:19 <DIR> .
2021/06/16 13:19 <DIR> ..
2021/05/10 08:28 3,059 sample.py
2021/05/18 16:53 119 user.csv
2021/05/14 10:31 <DIR> username
4

Sự khác biệt ở đây là với Windows, chúng ta cần chỉ định đường dẫn tới file thực thi của chương trình 7z, còn trong Ubuntu thì chúng ta chỉ cần viết câu lệnh trực tiếp

print(result.returncode) 
print(result.args)
3 mà thôi.

Sự khác nhau giữa subprocess.Popen() và subprocess.run()

Như ở phần trên Kiyoshi đã phân tích, thì chúng ta sử dụng subprocess.run() trong tất cả các trường hợp thông thường cần gọi một lệnh hoặc ứng dụng khác từ Python, và subprocess.Popen() trong các trường hợp cần có sự linh hoạt hơn trong xử lý. Subprocess.run() được thiết kế cho người dùng thông thường chỉ cần các chức năng đơn giản, và subprocess.Popen() do được cung cấp nhiều lựa chọn linh hoạt hơn nên được dành cho các nhà phát triển.

Tuy nhiên ngoài sự khác nhau về tính linh hoạt ở trên, thì sự khác nhau căn bản lớn nhất giữa subprocess.Popen() và subprocess.run() đó là subprocess.run() là xử lý đồng bộ và subprocess.Popen() là xử lý bất đồng bộ trong python.

subprocess.run() là xử lý đồng bộ, do đó nếu như ứng dụng hoặc lệnh được gọi từ subprocess.run() chưa chạy xong thì Python cũng sẽ không thể thực thi các lệnh tiếp theo trong chương trình. Bạn phải chờ cho đến khi nó kết thúc mới có thể tiếp tục xử lý chương trình.

Trong khi đó với subprocess.Popen(), do là xử lý bất đồng bộ nên bạn có thể thực hiện đồng thời các tác vụ khác hoặc xử lý kết quả nhận được ngay trong khi chờ ứng dụng kết thúc.

Do đó, tùy thuộc vào yêu cầu trong chương trình của mình mà bạn hãy lựa chọn hợp lý một trong hai phương pháp này để gọi lệnh hoặc ứng dụng khác từ Python.

Tổng kết

Trên đây Kiyoshi đã hướng dẫn bạn về cách sử dụng module subprocess trong Python để gọi một lệnh hoặc ứng dụng khác từ Python, cũng như cách dùng subprocess.run() và subprocess.Popen() trong module subprocess để xử lý đồng bộ và bất đồng bộ trong Python rồi. Để nắm rõ nội dung bài học hơn, bạn hãy thực hành viết lại các ví dụ của ngày hôm nay nhé.

Và hãy cùng tìm hiểu những kiến thức sâu hơn về python trong các bài học tiếp theo.

Viết bởi Kiyoshi. Đã đăng ký bản quyền tác giả tại <a title="Bạn được tự do chia sẻ bài viết nhưng phải để lại đường link bài viết từ laptrinhcanban.com. Bạn không được sử dụng tài liệu cho mục đích thương mại. Không được phép chỉnh sửa nội dung được phát hành trên website của chúng tôi" style="color:#fff;background-color:silver" rel="license noopener" target="_blank" href="https://creativecommons.org/licenses/by-nc-nd/4.0/">Creativecommons</a>&nbsp;và <a title="Bạn được tự do chia sẻ bài viết nhưng phải để lại đường link bài viết từ laptrinhcanban.com. Bạn không được sử dụng tài liệu cho mục đích thương mại. Không được phép chỉnh sửa nội dung được phát hành trên website của chúng tôi" style="color:#fff;background-color:silver" target="_blank" rel="noopener" href="https://www.dmca.com/Protection/Status.aspx?ID=1631afcd-7c4a-467d-8016-402c5073e5cd" class="dmca-badge">DMCA</a><script src="https://images.dmca.com/Badges/DMCABadgeHelper.min.js">

Bài viết liên quan

Hãy chia sẻ và cùng lan tỏa kiến thức lập trình Nhật Bản tại Việt Nam!

HOME>> >>

Profile
Hướng dẫn python subprocess get output - quy trình con python lấy đầu ra

Tác giả : Kiyoshi (Chis Thanh)

Kiyoshi là một cựu du học sinh tại Nhật Bản. Sau khi tốt nghiệp đại học Toyama năm 2017, Kiyoshi hiện đang làm BrSE tại Tokyo, Nhật Bản.