2010-08-13 13 views
9

Zastanawiałem się, czy uznano za dobry styl wywoływanie poleceń basha w skrypcie w języku Python za pomocą os.system(). Zastanawiałem się również, czy jest to bezpieczne, czy też nie.Czy dobrze jest wywoływać polecenia bash w skrypcie w języku Python za pomocą os.system ("bash code")?

Wiem, jak wdrożyć niektóre funkcje potrzebne w Bashu i Pythonie, ale jest o wiele prostsze i bardziej intuicyjne w implementacji w Bash. Jednak wydaje mi się, że pisanie os.system ("bash code") jest bardzo hackowe.

W szczególności chcę przenieść wszystkie pliki, które kończą się określonym rozszerzeniem do katalogu.

W bash: * mv .ext/ścieżka/do/przeznaczenia W Pythonie (pseudokod): do pliku w katalogu: jeśli file.endswith ("ext"): plik ruch do miejsca przeznaczenia

Co powinienem zrobić w tym przypadku?

+0

może wdrożyć funkcjonalność bash w skrypcie bash własnych i mają pyton wykonanie europejskiego skrypt bash sprzeciwia się umieszczeniu kodu kodu bezpośrednio w os.system()? (użyj najlepszego narzędzia do pracy) – Chris

+0

OK, dziękuję bardzo za twoją pomoc! Twoje odpowiedzi wyjaśniły mi pewne nieporozumienia w mojej głowie. Naprawdę doceniam wszystkie odpowiedzi. – JoeB

Odpowiedz

15

Przede wszystkim, przykład wykorzystuje mv, który to program w coreutils, nie bash.

Korzystanie os.system() wywołuje do zewnętrznych programów jest uważany za słabą styl, ponieważ:

  • Tworzycie zależności specyficzne dla platformy
  • tworzysz wersji zależności specyficznych (tak, nawet czasami zmienić coreutils !)
  • Musisz sprawdzić, czy istnieją zewnętrzne polecenia (i czy są one w $ PATH, i wykonywalne przez użytkownika itp.).
  • Musisz zawijać polecenia, sprawdzając błędy, używając ich kodu powrotu. O wiele lepiej jest używać kodów błędów lub wyjątków w języku. (os.system() nie pozwala ci parsować stdout/stderr)
  • Musisz radzić sobie z cytowaniem zmiennych spacjami samemu (lub ucieczce)
  • Python już wykonał pracę za Ciebie, dostarczając biblioteki!

Spójrz glob, na muszli jak pasujące do wzorca (globowania) i shutil, jak inni już wspomniano. W przeciwnym razie wszystko, czego potrzebujesz, znajduje się już w standardowych bibliotekach.

import glob 
import shutil 

for extfile in glob.glob('*.ext'): 
    shutil.move(extfile,dest) 

Ponadto os.system() nie powinny być stosowane - spojrzeć na subprocess zamiast modułu.

+1

Dobra odpowiedź, ale trochę się wzdrygam, gdy widzę zmienne o nazwie "plik", ponieważ ukrywa wbudowany plik. –

+0

Dobry komentarz - edytowany :) –

+0

Świetna odpowiedź, ale dla tych, którzy szukają więcej informacji o bash-> pythonie będę link do http://stackoverflow.com/questions/209470/can-i-use-python-as- a-bash-zamiennik – Nickolay

3

Zawsze lepszym i lepszym stylem jest używanie funkcji Pythona do robienia tego rodzaju rzeczy. W Pythonie nie jest trudno napisać skrypt w sposób niezależny od systemu operacyjnego, zamiast używać basha.

1

To nie jest pomysł, ponieważ powoduje, że twój skrypt jest mniej przenośny. Natywny skrypt Pythona może działać na dowolnym komputerze z systemem Unix lub Windows, który ma zainstalowane odpowiednie biblioteki Pythona. Po dodaniu poleceń powłoki do miksu, zostaje przerwana i nagle zostają zablokowane w znacznie węższym podzbiorze.

Czasami nie masz wyboru, ale jeśli jest to coś tak prostego, pisanie kodu natywnie w pythonie byłoby dużo bardziej sensowne, a także szybsze uruchamianie (ponieważ proces Pythona nie będzie miał aby utworzyć nową powłokę tylko po to, aby wykonać jedno polecenie).

6

Sprawdź moduł Pythona shutil. Oferuje operacje na systemie plików, takie jak przenoszenie plików. Pomiędzy nim a modułem os powinieneś mieć wszystkie potrzebne narzędzia. Jest to lepsze niż polecenie bash z powodów, które powiedzieli inni.

1

Samo cytowanie problemów sugeruje, że preferowane jest czyste rozwiązanie Pythona.

2

Kilka powodów dlaczego należy użyć czystego Python,

  1. Przy użyciu Python, już wykonane przy założeniu, że są zainstalowane Python i standardowych bibliotek. Używając kodu Bash w Pythonie, przyjmujesz założenie, że Bash jest zainstalowany i znajduje się na ścieżce systemowej.
  2. Wykorzystując kombinację dwóch językach robicie kod trudniejsze dla innych do czytania (nie każdy wie, Python i Bash)
  3. jeśli robisz to sposób Python będzie czuć się bardziej naturalne niedługo - mniej linie kodu nie zawsze są lepsze

W tym przypadku użyłbym ...

import os 
for filename in os.listdir('.'): 
    if filename.endswith('.ext'): 
    os.rename(filename, os.path.join('path', 'to', 'new', 'destination', filename)) 

Nie może być lepsze sposoby chociaż

+1

Możesz pozbyć się file.endswith(), jeśli używałbyś glob.glob ('*. Ext') zamiast os.listdir –

0

Mówiąc ogólniej, Python dostarcza moduł "podprocesu", który pozwala na uruchamianie poleceń i kontrolę nad ich wydajnością. To pozwala „odradzania nowe procesy, podłącz do swoich rur wejścia/wyjścia/błąd i uzyskać ich kody powrotne”:

http://docs.python.org/library/subprocess.html

Powiązane problemy