Існує чотири важкі випадки, коли віддавати перевагу більш конкретним методам Python в os
модулі над використанням os.system
або subprocess
модулем під час виконання команди:
- Надлишок - нерест іншого процесу є зайвим і витрачає час та ресурси.
- Переносимість - Багато методів у
os
модулі доступні на декількох платформах, в той час як багато команд оболонки мають специфічну для ОС.
- Розуміння результатів - Нерестування процесу виконання довільних команд змушує вас розібрати результати з результату та зрозуміти, якщо і чому команда зробила щось не так.
- Безпека - процес може потенційно виконувати будь-яку задану йому команду. Це слабка конструкція, і цього можна уникнути, використовуючи конкретні методи в
os
модулі.
Ви насправді виконуєте зайвого «середнього чоловіка» на шляху до можливих системних викликів ( chmod
у вашому прикладі). Цей середній чоловік - це новий процес або підрозділ.
Від os.system
:
Виконайте команду (рядок) у нижній частині ...
І subprocess
це лише модуль для нересту нових процесів.
Ви можете робити все, що вам потрібно, не породжуючи цих процесів.
Переносність (див. Портативність вихідного коду ):
Метою os
модуля є надання загальних послуг операційної системи, і його опис починається з:
Цей модуль пропонує портативний спосіб використання функціональних можливостей, залежних від операційної системи.
Ви можете використовувати os.listdir
як Windows, так і Unix. Спроба використовувати os.system
/ subprocess
для цієї функції змусить вас підтримувати два дзвінки (для ls
/ dir
) і перевірити, на якій операційній системі ви працюєте. Це не так портативно, і згодом викличе ще більше розчарувань (див. Поводження з результатами ).
Розуміння результатів команди:
Припустимо, ви хочете перерахувати файли в каталозі.
Якщо ви використовуєте os.system("ls")
/ subprocess.call(['ls'])
, ви можете отримати лише вихідний результат процесу, який в основному є великим рядком з іменами файлів.
Як ви можете розпізнати файл із пробілом у його імені з двох файлів?
Що робити, якщо у вас немає дозволу на перелік файлів?
Як слід відображати дані на об’єкти python?
Це лише у верхній частині моєї голови, і поки є рішення цих проблем - навіщо знову вирішувати проблему, вирішену для вас?
Це приклад дотримання принципу " Не повторюй себе" (часто його називають "DRY"), не повторюючи реалізацію, яка вже існує і доступна для вас.
Безпека:
os.system
і subprocess
є потужними. Це добре, коли вам потрібна ця сила, але небезпечно, коли ви цього не робите. Під час використання os.listdir
ви знаєте, що він не може робити нічого іншого, крім списку файлів або помилки. Коли ви використовуєте os.system
та subprocess
домагаєтесь такої ж поведінки, ви потенційно можете зробити щось, чого ви не хотіли робити.
Безпека ін'єкцій (див. Приклади введення оболонки ) :
Якщо ви використовуєте дані користувача як нову команду, ви в основному дали йому оболонку. Це так само, як інжекція SQL, що забезпечує оболонку в БД для користувача.
Прикладом може бути команда форми:
# ... read some user input
os.system(user_input + " some continutation")
Це можна легко використовувати для запуску будь-якого довільного коду за допомогою вводу: NASTY COMMAND;#
для створення можливого:
os.system("NASTY COMMAND; # some continuation")
Є багато таких команд, які можуть піддавати вашій системі небезпеку.