Có bốn trường hợp mạnh để ưu tiên các phương thức cụ thể hơn của Python trong os
mô-đun hơn là sử dụng os.system
hoặc subprocess
mô-đun khi thực hiện lệnh:
- Dư - sinh ra một quá trình khác là dư thừa và lãng phí thời gian và tài nguyên.
- Tính di động - Nhiều phương thức trong
os
mô-đun có sẵn trong nhiều nền tảng trong khi nhiều lệnh shell là đặc thù của os.
- Hiểu kết quả - Tạo ra một quy trình để thực thi các lệnh tùy ý buộc bạn phải phân tích kết quả từ đầu ra và hiểu nếu và tại sao một lệnh đã làm sai.
- An toàn - Một quy trình có khả năng thực thi bất kỳ lệnh nào được đưa ra. Đây là một thiết kế yếu và nó có thể tránh được bằng cách sử dụng các phương pháp cụ thể trong
os
mô-đun.
Bạn đang thực sự thực hiện một "người trung gian" dư thừa trên đường đến các cuộc gọi hệ thống cuối cùng (chmod
trong ví dụ của bạn). Người đàn ông trung lưu này là một quá trình mới hoặc vỏ phụ.
Từ os.system
:
Thực hiện lệnh (một chuỗi) trong một khung con ...
Và subprocess
chỉ là một mô-đun để sinh ra các quy trình mới.
Bạn có thể làm những gì bạn cần mà không sinh ra các quá trình này.
Các os
mục tiêu của Module này là để cung cấp các dịch vụ hệ điều hành chung và nó bắt đầu mô tả với:
Mô-đun này cung cấp một cách di động sử dụng chức năng phụ thuộc hệ điều hành.
Bạn có thể sử dụng os.listdir
trên cả windows và unix. Cố gắng sử dụng os.system
/ subprocess
cho chức năng này sẽ buộc bạn phải duy trì hai cuộc gọi (cho ls
/ dir
) và kiểm tra xem bạn đang sử dụng hệ điều hành nào. Đây không phải là di động và sẽ gây ra sự thất vọng nhiều hơn về sau (xem Xử lý đầu ra ).
Hiểu kết quả của lệnh:
Giả sử bạn muốn liệt kê các tập tin trong một thư mục.
Nếu bạn đang sử dụng os.system("ls")
/ subprocess.call(['ls'])
, bạn chỉ có thể lấy lại đầu ra của quy trình, về cơ bản là một chuỗi lớn có tên tệp.
Làm thế nào bạn có thể nói một tệp có một khoảng trắng trong tên của nó từ hai tệp?
Điều gì nếu bạn không có quyền liệt kê các tập tin?
Làm thế nào bạn nên ánh xạ dữ liệu đến các đối tượng python?
Những điều này chỉ nằm ngoài đỉnh đầu của tôi, và trong khi có những giải pháp cho những vấn đề này - tại sao lại giải quyết một vấn đề đã được giải quyết cho bạn?
Đây là một ví dụ về việc tuân thủ nguyên tắc Đừng lặp lại chính mình (Thường được gọi là "DRY") bằng cách không lặp lại một triển khai đã tồn tại và có sẵn miễn phí cho bạn.
Sự an toàn:
os.system
và subprocess
có sức mạnh Thật tốt khi bạn cần sức mạnh này, nhưng nó nguy hiểm khi bạn không. Khi bạn sử dụng os.listdir
, bạn biết nó không thể làm gì khác ngoài việc liệt kê các tệp hoặc đưa ra lỗi. Khi bạn sử dụng os.system
hoặcsubprocess
để đạt được hành vi tương tự, bạn có khả năng sẽ làm điều gì đó mà bạn không có ý định làm.
Tiêm an toàn (xem ví dụ tiêm vỏ ) :
Nếu bạn sử dụng đầu vào từ người dùng như một lệnh mới, về cơ bản bạn đã đưa cho anh ta một vỏ. Điều này giống như SQL tiêm cung cấp shell trong DB cho người dùng.
Một ví dụ sẽ là một lệnh của mẫu:
# ... read some user input
os.system(user_input + " some continutation")
Điều này có thể dễ dàng khai thác để chạy bất kỳ mã tùy ý nào bằng cách sử dụng đầu vào: NASTY COMMAND;#
để tạo cuối cùng:
os.system("NASTY COMMAND; # some continuation")
Có rất nhiều lệnh như vậy có thể khiến hệ thống của bạn gặp rủi ro.