Cách thực thi các lệnh Shell bằng Python bằng cách sử dụng phương thức chạy quy trình con

How Execute Shell Commands Python Using Subprocess Run Method



Quy trình con là một mô-đun Python được tích hợp sẵn có thể được sử dụng để tạo các quy trình mới và tương tác với các luồng dữ liệu đầu vào và đầu ra của chúng. Nói một cách đơn giản hơn, bạn có thể sử dụng nó để chạy các lệnh shell và chạy các tệp nhị phân thực thi thường nằm rải rác trong các thư mục bin khác nhau trên hệ thống tệp Linux. Bạn cũng có thể cung cấp một đường dẫn đầy đủ đến một tệp nhị phân thực thi và sử dụng bất kỳ công tắc dòng lệnh nào được liên kết với tệp nhị phân. Bài viết này sẽ giải thích cách sử dụng mô-đun quy trình con và phương pháp chạy của nó trong các ứng dụng Python. Tất cả các mẫu mã trong bài viết đều được thử nghiệm với Python 3.8.2 trên Ubuntu 20.04.

Phương thức Subprocess.run

Phương thức Subprocess.run nhận một danh sách các đối số. Khi phương thức được gọi, nó thực hiện lệnh và đợi quá trình kết thúc, cuối cùng trả về một đối tượng CompletedProcess. Đối tượng CompletedProcess trả về các đối số stdout, stderr, ban đầu được sử dụng trong khi gọi phương thức và một mã trả về. Stdout đề cập đến luồng dữ liệu được tạo ra bởi lệnh, trong khi stderr đề cập đến bất kỳ lỗi nào được phát sinh trong quá trình thực thi chương trình. Bất kỳ mã trả về nào khác 0 (mã thoát) sẽ có nghĩa là lỗi với lệnh được thực thi trong phương thức subprocess.run.







Ví dụ 1: Nội dung đầu ra của một tệp văn bản sử dụng phương thức Subprocess.run

Lệnh dưới đây sẽ xuất ra nội dung của tệp data.txt, giả sử rằng nó chứa chuỗi tên = John.



nhập khẩu quy trình phụ
quy trình phụ.chạy(['con mèo', 'data.txt'])

Chạy đoạn mã trên sẽ trả về kết quả sau:



Tên=John
Đã hoàn thành(args=['con mèo', 'data.txt'],mã trả lại=0)

Phần tử đầu tiên của đối số danh sách là tên của lệnh sẽ được thực thi. Bất kỳ phần tử nào trong danh sách theo sau phần tử đầu tiên đều được coi là các tùy chọn dòng lệnh hoặc công tắc. Bạn cũng có thể sử dụng dấu gạch ngang đơn và dấu gạch ngang kép để xác định các tùy chọn. Ví dụ: để liệt kê các tệp và thư mục trong một thư mục, mã sẽ là subprocess.run ([ls, -l]. Trong hầu hết các trường hợp này, bạn có thể coi bất kỳ đối số được phân tách bằng dấu cách nào trong lệnh shell là một phần tử riêng lẻ trong danh sách được cung cấp cho phương thức subprocess.run.





Ví dụ 2: Loại bỏ đầu ra của phương thức Subprocess.run

Để loại bỏ đầu ra của phương thức subprocess.run, bạn sẽ phải cung cấp stdout = subprocess.DEVNULL và stderr = subprocess.DEVNULL làm đối số bổ sung.

nhập khẩu quy trình phụ

quy trình phụ.chạy(['con mèo', 'data.txt'],stdout=quy trình phụ.DEVNULL,
stderr=quy trình phụ.DEVNULL)

Chạy đoạn mã trên sẽ tạo ra kết quả sau:



CompletedProcess (args = ['cat', 'data.txt'], returnncode = 0)

Ví dụ 3: Chụp đầu ra của phương thức Subprocess.run

Để nắm bắt đầu ra của phương thức subprocess.run, hãy sử dụng một đối số bổ sung có tên là capture_output = True.

nhập khẩu quy trình phụ
đầu ra= quy trình phụ.chạy(['con mèo', 'data.txt'],capture_output=Thật)
in (đầu ra)

Chạy đoạn mã trên sẽ tạo ra kết quả sau:

Đã hoàn thành(args=['con mèo', 'data.txt'],mã trả lại=0,
stdout=NS'name = John ',stderr=NS'')

Bạn có thể truy cập từng giá trị stdout và stderr bằng cách sử dụng các phương thức output.stdout và output.stderr. Đầu ra được tạo ra dưới dạng một chuỗi byte. Để lấy một chuỗi làm đầu ra, hãy sử dụng phương thức output.stdout.decode (utf-8). Bạn cũng có thể cung cấp text = True làm đối số bổ sung cho lệnh gọi subprocess.run để nhận kết quả ở định dạng chuỗi. Để lấy mã trạng thái thoát, bạn có thể sử dụng phương thức output.returncode.

Ví dụ 4: Tăng ngoại lệ khi không thực hiện được lệnh bằng phương thức Subprocess.run

Để đưa ra một ngoại lệ khi lệnh thoát với trạng thái khác 0, hãy sử dụng đối số check = True.

nhập khẩu quy trình phụ
quy trình phụ.chạy(['con mèo', 'data.tx'],capture_output=Thật,chữ=Thật,đánh dấu=Thật)

Chạy đoạn mã trên sẽ tạo ra kết quả sau:

nâng CalledProcessError (mã lại, process.args,
subprocess.CalledProcessError: Command '[' cat ',' data.tx ']'
trả về trạng thái thoát khác 0 1.

Ví dụ 5: Truyền một chuỗi đến lệnh được thực thi bởi phương thức Subprocess.run

Bạn có thể truyền một chuỗi vào lệnh sẽ được thực thi bởi phương thức subprocess.run bằng cách sử dụng đối số input = ’string’.

nhập khẩu quy trình phụ
đầu ra= quy trình phụ.chạy(['con mèo'], đầu vào='data.txt',capture_output=Thật,
chữ=Thật,đánh dấu=Thật)
in (đầu ra)

Chạy đoạn mã trên sẽ tạo ra kết quả sau:

CompletedProcess (args = ['cat'], returnncode = 0, stdout = 'data.txt', stderr = '')

Như bạn có thể thấy, đoạn mã trên chuyển data.txt dưới dạng một chuỗi chứ không phải là một đối tượng tệp. Để chuyển data.txt dưới dạng tệp, hãy sử dụng đối số stdin.

với mở ra('data.txt') nhưNS:
đầu ra= quy trình phụ.chạy(['con mèo'],stdin=NS,capture_output=Thật,
chữ=Thật,đánh dấu=Thật)
in (đầu ra)

Chạy đoạn mã trên sẽ tạo ra kết quả sau:

CompletedProcess (args = ['cat'], returnncode = 0, stdout = 'name = John n', stderr = '')

Ví dụ 6: Thực thi lệnh trực tiếp trong Shell bằng phương thức Subprocess.run

Có thể chạy một lệnh trực tiếp vào một trình bao thay vì sử dụng phân chia chuỗi trong lệnh chính và các tùy chọn theo sau nó. Để làm điều này, bạn phải chuyển shell = True làm đối số bổ sung. Tuy nhiên, điều này không được các nhà phát triển python khuyến khích vì việc sử dụng shell = True có thể dẫn đến các vấn đề bảo mật. Bạn có thể đọc thêm về các tác động bảo mật từ ở đây .

nhập khẩu quy trình phụ
quy trình phụ.chạy('cat' data.txt '',vỏ bọc=Thật)

Chạy đoạn mã trên sẽ tạo ra kết quả sau:

name = John

Phần kết luận

Phương thức subprocess.run trong Python khá mạnh vì nó cho phép bạn chạy các lệnh shell trong chính python. Điều này giúp hạn chế tất cả mã trong chính python mà không cần phải có mã tập lệnh shell bổ sung trong các tệp riêng biệt. Tuy nhiên, có thể khá phức tạp để mã hóa các lệnh shell một cách chính xác trong danh sách python. Bạn có thể sử dụng phương thức shlex.split () để mã hóa các lệnh shell đơn giản, nhưng trong các lệnh dài, phức tạp - đặc biệt là các lệnh có ký hiệu ống - shlex không thể chia lệnh chính xác. Trong những trường hợp như vậy, gỡ lỗi có thể là một vấn đề phức tạp. Bạn có thể sử dụng đối số shell = True để tránh điều này, nhưng có một số lo ngại về bảo mật liên quan đến hành động này.