Istnieją cztery mocne argumenty przemawiające za preferowaniem bardziej specyficznych metod Pythona w os
module zamiast używania os.system
lub subprocess
modułu podczas wykonywania polecenia:
- Nadmiarowość - tworzenie kolejnego procesu jest zbędne i powoduje marnowanie czasu i zasobów.
- Przenośność - wiele metod
os
modułu jest dostępnych na wielu platformach, podczas gdy wiele poleceń powłoki jest specyficznych dla systemu operacyjnego.
- Zrozumienie wyników - tworzenie procesu wykonującego dowolne polecenia zmusza do przeanalizowania wyników z danych wyjściowych i zrozumienia, czy i dlaczego polecenie spowodowało coś złego.
- Bezpieczeństwo - proces może potencjalnie wykonać każde wydane polecenie. Jest to słaby projekt i można go uniknąć, stosując określone metody w
os
module.
W rzeczywistości wykonujesz zbędnego „pośrednika” w drodze do ewentualnych wywołań systemowych ( chmod
w twoim przykładzie). Ten pośrednik jest nowym procesem lub podpowłoką.
Od os.system
:
Wykonaj polecenie (ciąg) w podpowłoce ...
I subprocess
jest tylko moduł do odradzania nowych procesów.
Możesz robić to, czego potrzebujesz, bez tworzenia tych procesów.
Celem os
modułu jest zapewnienie ogólnych usług systemu operacyjnego, a jego opis zaczyna się od:
Ten moduł zapewnia przenośny sposób korzystania z funkcji zależnych od systemu operacyjnego.
Możesz używać os.listdir
zarówno w systemie Windows, jak i unix. Próba użycia os.system
/ subprocess
do tej funkcji zmusi Cię do utrzymania dwóch wywołań (dla ls
/ dir
) i sprawdzenia, w jakim systemie operacyjnym jesteś. To nie jest tak przenośny i będzie powodować jeszcze większą frustrację później (patrz Magazynowanie Output ).
Zrozumienie wyników polecenia:
Załóżmy, że chcesz wyświetlić listę plików w katalogu.
Jeśli używasz os.system("ls")
/ subprocess.call(['ls'])
, możesz odzyskać tylko dane wyjściowe procesu, które są w zasadzie dużym ciągiem z nazwami plików.
Jak odróżnić plik ze spacją w nazwie od dwóch plików?
A jeśli nie masz uprawnień do wyświetlania plików?
Jak należy odwzorować dane na obiekty Pythona?
Są to tylko z góry mojej głowy, i chociaż istnieją rozwiązania tych problemów - po co rozwiązywać ponownie problem, który został rozwiązany za Ciebie?
To jest przykład przestrzegania zasady „ Nie powtarzaj się ” (często określanej jako „SUCHA”) poprzez nie powtarzanie implementacji, która już istnieje i jest dostępna bezpłatnie.
Bezpieczeństwo:
os.system
i subprocess
są potężne. Dobrze, gdy potrzebujesz tej mocy, ale jest to niebezpieczne, gdy jej nie potrzebujesz. Kiedy używasz os.listdir
, wiesz, że nie może zrobić nic innego niż wyświetlenie plików lub zgłoszenie błędu. Kiedy używasz os.system
lub subprocess
osiągasz to samo zachowanie, możesz potencjalnie zrobić coś, czego nie chciałeś zrobić.
Bezpieczeństwo wtrysku (patrz przykłady wtrysku powłoki ) :
Jeśli używasz danych wejściowych od użytkownika jako nowego polecenia, w zasadzie dałeś mu powłokę. Jest to podobne do iniekcji SQL zapewniającej użytkownikowi powłokę w bazie danych.
Przykładem może być polecenie w postaci:
# ... read some user input
os.system(user_input + " some continutation")
To może być łatwo wykorzystany do uruchomienia dowolnego dowolnego kodu przy użyciu wkład: NASTY COMMAND;#
stworzyć ostateczne:
os.system("NASTY COMMAND; # some continuation")
Istnieje wiele takich poleceń, które mogą stanowić zagrożenie dla systemu.