Jak zaimplementować popularne idiomy bash w Pythonie? [Zamknięte]

242

Obecnie manipuluję plikami tekstowymi przez grupę źle zapamiętanych AWK, sed, Bash i trochę Perla.

Widziałem już kilka miejsc, w których Python nadaje się do tego rodzaju rzeczy. Jak mogę użyć Pythona do zastąpienia skryptów powłoki, AWK, sed i znajomych?

Chris Jefferson
źródło
3
pythonpy jest dobrym konkurentem dla awk i sed przy użyciu składni python: github.com/Russell91/pythonpy
RussellStewart
4
możesz użyć skorupki, która została zaprojektowana z myślą o zastąpieniu bash / sh python github.com/lamerman/shellpy
Alexander Ponomarev
To moje pytanie, nie rozumiem, dlaczego opiera się na opiniach. W górnej odpowiedzi wymieniono każdą z głównych czynności wykonywanych przez powłokę i podpowiemy, jak to zrobić w Pythonie. To moim zdaniem odpowiada na pytanie w sposób bezstronny.
Chris Jefferson,
To pytanie i jego zamknięcie są omawiane tutaj
Erik A

Odpowiedzi:

144

Każda powłoka ma kilka zestawów funkcji.

  • Komendy Essential Linux / Unix. Wszystkie są dostępne za pośrednictwem biblioteki podprocesów . Nie zawsze jest to najlepszy pierwszy wybór do wykonywania wszystkich poleceń zewnętrznych. Spójrz także na shutil, aby zapoznać się z niektórymi komendami, które są oddzielnymi komendami Linuksa, ale prawdopodobnie możesz je zaimplementować bezpośrednio w skryptach Pythona. Kolejna duża partia poleceń Linuksa znajduje się w bibliotece os ; możesz to zrobić po prostu w Pythonie.

    I - bonus! -- szybciej. Każde osobne polecenie Linuksa w powłoce (z kilkoma wyjątkami) wywołuje podproces. Używając Pythona shutili osmodułów, nie rozwidlasz podprocesu.

  • Funkcje środowiska powłoki. Obejmuje to rzeczy, które ustawiają środowisko polecenia (bieżący katalog i zmienne środowiskowe oraz what-not). Możesz łatwo zarządzać tym bezpośrednio z Pythona.

  • Funkcje programowania powłoki. To jest sprawdzanie kodu statusu procesu, różne polecenia logiczne (jeśli, podczas, dla itd.) Polecenie testowe i wszyscy jego krewni. Definicja funkcji. W Pythonie jest to o wiele łatwiejsze. To jedno z wielkich zwycięstw w pozbyciu się bashu i zrobieniu tego w Pythonie.

  • Funkcje interakcji Obejmuje to historię poleceń i takie tam. Nie potrzebujesz tego do pisania skryptów powłoki. Dotyczy to wyłącznie interakcji międzyludzkich, a nie pisania scenariuszy.

  • Funkcje zarządzania plikami powłoki. Obejmuje to przekierowanie i potoki. To trudniejsze. Wiele z tego można zrobić za pomocą podprocesu. Ale niektóre rzeczy, które są łatwe w powłoce, są nieprzyjemne w Pythonie. W szczególności rzeczy takie jak (a | b; c ) | something >result. To uruchamia dwa procesy równolegle (z wyjściem ajako wejście do b), a następnie trzeci proces. Dane wyjściowe z tej sekwencji są uruchamiane równolegle, somethinga dane wyjściowe są gromadzone w pliku o nazwie result. To skomplikowane do wyrażenia w dowolnym innym języku.

Określone programy (awk, sed, grep itp.) Często można przepisać jako moduły Pythona. Nie idź za burtę. Wymień to, czego potrzebujesz i rozwinąć moduł „grep”. Nie zaczynaj pisać modułu Python, który zastępuje „grep”.

Najlepsze jest to, że możesz to zrobić krok po kroku.

  1. Zamień AWK i PERL na Python. Zostaw wszystko inne w spokoju.
  2. Spójrz na zastąpienie GREP Pythonem. Może to być nieco bardziej złożone, ale twoja wersja GREP może być dostosowana do twoich potrzeb przetwarzania.
  3. Spójrz na zamianę FIND na używane pętle Pythona os.walk. To duża wygrana, ponieważ nie spawnujesz tylu procesów.
  4. Spójrz na zastąpienie typowej logiki powłoki (pętle, decyzje itp.) Skryptami w języku Python.
S.Lott
źródło
6
napisał: „Funkcje interakcji. Obejmuje to historię poleceń i co nie. Nie potrzebujesz tego.” Obawiam się, że nikt nie jest w stanie powiedzieć, czego naprawdę potrzebuje osoba. Być może on. Poza tym, te funkcje mają sens w interaktywnej powłoce, biorąc za przykład różnicę między Idle a IPython.
heltonbiker
47
Szczerze chciałbym, żeby ludzie porzucili skrypty powłoki. Rozumiem, że hackowanie jest praktycznie religią w świecie * nix, ale mam już dość próby interpretacji wszystkich hackerskich obejść zaimplementowanych w systemie operacyjnym. Nowość mikrotoolów (awk, sed, top, base itp.) Przeminęła w dniu, w którym wszyscy postanowili wypuścić własną wersję. Kulę się, gdy wyobrażam sobie ilość roboczogodzin marnowanych na gównianych, małych narzędziach, które można łatwo zastąpić kilkoma dobrze zaprojektowanymi modułami Pythona. :: westchnienie ::
Evan Plaice
40
Nie zgadzam się z @EvanPlaice, ponieważ wersja kilku findskryptów w języku Python, którą mam, jest brzydka, długa i niemożliwa do utrzymania w porównaniu. Wiele rzeczy powinno być skryptami powłoki, wiele innych nie . Nie wszystko musi być tylko jednym z Python lub BASH (lub cokolwiek innego).
mikebabcock
8
@mikebabcock Idealnie byłoby mieć pełną bibliotekę, która implementuje wszystkie mikro-narzędzia udostępniane przez podstawowy stos * nix. Funkcje takie jak find () i last () byłyby włączone i zamiast rur, połączenie curry i leniwego ładowania poradziłoby sobie z klejeniem tego wszystkiego razem. Czy nie byłoby miło mieć środowisko skryptowe POSIX, które działa w standardowy sposób we wszystkich dystrybucjach? Nic takiego nie istnieje, jeszcze ...
Evan Plaice
2
Problem dotyczący rurociągów powłokowych (takich jak (a | b; c ) | something >result) jest nieco złagodzony, ponieważ w prosty sposób można przekazywać rurociągi powłokowe do subprocessmetod przy użyciushell=True
iruvar
103

Tak oczywiście :)

Spójrz na te biblioteki, które pomogą Ci nigdy więcej nie pisać skryptów powłoki (motto Plumbum).

Ponadto, jeśli chcesz zastąpić awk, sed i grep czymś opartym na Pythonie, polecam pyp -

„Pyed Piper”, czyli pyp, to narzędzie do manipulacji tekstem w wierszu poleceń, podobne do awk lub sed, ale które wykorzystuje standardowe metody napisów i list w Pythonie, a także opracowane niestandardowe funkcje w celu generowania szybkich wyników w intensywnym środowisku produkcyjnym.

Piotr Dobrogost
źródło
Zobacz także wysłannika, który jest alternatywą dla sh github.com/kennethreitz/envoy
AllanLRH
57

Właśnie odkryłem, jak połączyć najlepsze części bash i ipython. Do tej pory wydawało mi się to wygodniejsze niż używanie podprocesu i tak dalej. Możesz łatwo skopiować duże części istniejących skryptów bash i np. Dodać obsługę błędów w sposób pythonowy :) A oto mój wynik:

#!/usr/bin/env ipython3

# *** How to have the most comfort scripting experience of your life ***
# ######################################################################
#
# … by using ipython for scripting combined with subcommands from bash!
#
# 1. echo "#!/usr/bin/env ipython3" > scriptname.ipy    # creates new ipy-file
#
# 2. chmod +x scriptname.ipy                            # make in executable
#
# 3. starting with line 2, write normal python or do some of
#    the ! magic of ipython, so that you can use unix commands
#    within python and even assign their output to a variable via
#    var = !cmd1 | cmd2 | cmd3                          # enjoy ;)
#
# 4. run via ./scriptname.ipy - if it fails with recognizing % and !
#    but parses raw python fine, please check again for the .ipy suffix

# ugly example, please go and find more in the wild
files = !ls *.* | grep "y"
for file in files:
  !echo $file | grep "p"
# sorry for this nonsense example ;)

Zobacz dokumentację IPython dotyczącą poleceń powłoki systemowej i używania jej jako powłoki systemowej .

TheK
źródło
11
Pozytywne, ponieważ z jakiegoś dziwnego powodu nikt inny nie wspomniał! -Polecenia w IPython, które są absolutnie kluczowe; tym bardziej, że możesz przypisać ich dane wyjściowe do zmiennej (listy linii), tak jak infilelines = ! cat myfile
kampu
I możesz używać zmiennych python jak $varw poleceniu powłoki? Łał. To powinna być zaakceptowana odpowiedź.
Chiel ten Brinke
Możesz także użyć go z notatników jupyter
Yuval Atzmon
44

Począwszy od 2015 r. I wydania Python 3.4, dostępna jest w miarę kompletna powłoka interaktywna dla użytkownika dostępna pod adresem: http://xon.sh/ lub https://github.com/scopatz/xonsh

Film demonstracyjny nie pokazuje używanych rur, ale są one obsługiwane w domyślnym trybie powłoki.

Xonsh („muszla”) bardzo mocno próbuje emulować uderzenie, więc na przykład dla rzeczy, które już zyskałeś pamięć mięśni

env | uniq | sort -r | grep PATH

lub

my-web-server 2>&1 | my-log-sorter

nadal będzie działać dobrze.

Samouczek jest dość długi i wydaje się, że obejmuje znaczną część funkcjonalności, jakiej można by się spodziewać po monicie:

  • Kompiluje, ocenia i wykonuje!
  • Historia poleceń i wypełnianie kart
  • Pomoc i pomoc ? &??
  • Aliasy i niestandardowe monity
  • Wykonuje polecenia i / lub *.xsh skrypty, które można również importować
  • Zmienne środowiskowe, w tym Wyszukiwanie za pomocą ${}
  • Przekierowywanie i łączenie danych wejściowych / wyjściowych
  • Zadania w tle i kontrola zadań
  • Zagnieżdżanie podprocesów, rur i koprocesów
  • Tryb podprocesu, gdy istnieje polecenie, w przeciwnym razie tryb Pythona
  • Captured Subprocess with $(), Uncaptured Subprocess with $[], Python Evaluation with@()
  • Globbing *nazwy pliku z lub wyrażenie regularne Globbing nazwy pliku z backtiksem
Kamilion
źródło
Ale dlaczego wydaje się, że wszystkie te odpowiedzi zmieniają kierownicę dla ludzi, którzy nie znają bashu ? Uzyskałem umiarkowaną wygodę w bashu i każda z tych odpowiedzi wygląda na to, że skończy się to większą pracą przynosząc niewielkie korzyści. Wszystkie te odpowiedzi są skierowane do pythonów, którzy boją się (lub nie chcą tracić czasu na naukę) bash, mam rację?
Buttle Butkus,
Wydaje się, że ma pewne wady, takie jak wymóg używania .xshrozszerzenia dla plików z kodem xonsh : github.com/xonsh/xonsh/issues/2478 . W przeciwnym razie musisz użyć, evalxaby wywołać go bezpośrednio z .pyplików.
Andry
31
  • Jeśli chcesz używać Pythona jako powłoki, dlaczego nie spojrzeć na IPython ? Dobrze jest także uczyć się interaktywnie języka.
  • Jeśli wykonujesz dużo manipulacji tekstem i używasz Vima jako edytora tekstu, możesz także bezpośrednio pisać wtyczki dla Vima w pythonie. po prostu wpisz „: help python” w Vimie i postępuj zgodnie z instrukcjami lub spójrz na tę prezentację . Pisanie funkcji, których będziesz używać bezpośrednio w edytorze, jest tak łatwe i wydajne!
Mapad
źródło
8
istnieje profil ipython o nazwie „sh”, który sprawia, że ​​interpreter jest bardzo podobny do powłoki.
Autoplectic
3
Profil „sh” ipython został już na jakiś czas usunięty.
gdw2
>>> wynik =! dmesg | grep -i 'usb' #the! operator robi wszystko
Permafacture
16

Na początku było sh, sed i awk (i znajdź, grep i ...). To było dobre. Ale awk może być dziwną małą bestią i trudno ją zapamiętać, jeśli nie używasz jej często. Następnie wielki wielbłąd stworzył Perla. Perl był marzeniem administratora systemu. To było jak pisanie skryptów na sterydach. Przetwarzanie tekstu, w tym wyrażenia regularne, było po prostu częścią języka. Potem stało się brzydkie ... Ludzie próbowali tworzyć duże aplikacje za pomocą Perla. Nie zrozum mnie źle, Perl może być aplikacją, ale może (może!) Wyglądać jak bałagan, jeśli nie jesteś naprawdę ostrożny. Potem jest cały ten płaski biznes danych. Wystarczy doprowadzić do szału programisty.

Wpisz Python, Ruby i in. To naprawdę bardzo dobre języki ogólnego przeznaczenia. Obsługują przetwarzanie tekstu i robią to dobrze (choć być może nie są tak ściśle powiązane z podstawowym rdzeniem języka). Ale skalują się również bardzo dobrze i pod koniec dnia wciąż mają ładnie wyglądający kod. Stworzyli też całkiem spore społeczności z dużą ilością bibliotek dla większości czegokolwiek.

Teraz wiele negatywnych opinii na temat Perla jest kwestią opinii i na pewno niektórzy ludzie potrafią napisać bardzo czysty Perl, ale przy tak wielu ludziach narzekających na to, że zbyt łatwe jest tworzenie zaciemnionego kodu, wiesz, że jest w tym trochę ziarna prawdy. Powstaje więc pytanie: czy kiedykolwiek użyjesz tego języka do czegoś więcej niż zwykłego zastępowania skryptu bash. Jeśli nie, naucz się więcej Perla ... jest to absolutnie fantastyczne. Jeśli natomiast chcesz języka, który będzie się rozwijał wraz z tobą, aby zrobić więcej, pozwól, że zasugeruję Python lub Ruby.

Tak czy inaczej, powodzenia!

MattG
źródło
9

Proponuję niesamowitą książkę online Dive Into Python . Tak pierwotnie nauczyłem się języka.

Oprócz nauki podstawowej struktury języka i wielu użytecznych struktur danych, ma także dobry rozdział na temat obsługi plików i kolejne rozdziały na temat wyrażeń regularnych i wiele więcej.

Dan Lenski
źródło
1
... główny problem odpowiedzi tylko w linkach.
Jean-François Fabre
7

Dodanie do poprzednich odpowiedzi: sprawdź moduł pexpect pod kątem obsługi poleceń interaktywnych (adduser, passwd itp.)

Federico A. Ramponi
źródło
7

Jednym z powodów, dla których uwielbiam Python jest to, że jest on znacznie lepiej znormalizowany niż narzędzia POSIX. Muszę podwójnie i potrójnie sprawdzić, czy każdy bit jest zgodny z innymi systemami operacyjnymi. Program napisany w systemie Linux może nie działać tak samo w systemie BSD OSX. W Pythonie muszę tylko sprawdzić, czy system docelowy ma wystarczająco nowoczesną wersję Pythona.

Co więcej, program napisany w standardowym języku Python działa nawet w systemie Windows!

Hal Canary
źródło
1
„program napisany w standardowym języku Python będzie nawet działał w systemie Windows”: nie żartujesz?
Jean-François Fabre
6

Podam tutaj moją opinię na podstawie doświadczenia:

Dla powłoki:

  • powłoka może bardzo łatwo spawnować kod tylko do odczytu. Napisz to, a kiedy do niej wrócisz, nigdy więcej nie dowiesz się, co zrobiłeś. Bardzo łatwo to osiągnąć.
  • shell może wykonać DUŻO przetwarzania tekstu, dzielenia itp. w jednym wierszu z potokami.
  • jest to najlepszy język kleju, jeśli chodzi o integrację wywołania programów w różnych językach programowania.

W przypadku python:

  • jeśli chcesz mieć możliwość przenoszenia do systemu Windows, użyj Pythona.
  • Python może być lepszy, gdy musisz manipulować tylko czymś więcej niż tekstem, takim jak zbiory liczb. Do tego polecam python.

Zazwyczaj wybieram bash dla większości rzeczy, ale kiedy mam coś, co musi przekraczać granice systemu Windows, po prostu używam Pythona.

Germán Diago
źródło
4

pythonpy to narzędzie, które zapewnia łatwy dostęp do wielu funkcji z awk i sed, ale przy użyciu składni python:

$ echo me2 | py -x 're.sub("me", "you", x)'
you2
RussellStewart
źródło
3

Zbudowałem półdługie skrypty powłoki (300-500 linii) i kod Pythona, który ma podobną funkcjonalność. Kiedy wykonywanych jest wiele zewnętrznych poleceń, uważam, że powłoka jest łatwiejsza w użyciu. Perl jest również dobrą opcją, gdy istnieje wiele manipulacji tekstem.

Mike Davis
źródło
2

Twój najlepszy zakład to narzędzie, które jest specjalnie dostosowane do Twojego problemu. Jeśli przetwarza pliki tekstowe, Sed, Awk i Perl są najlepszymi konkurentami. Python jest dynamiką ogólnego przeznaczenia językiem . Jak w każdym języku ogólnego przeznaczenia, istnieje możliwość manipulowania plikami, ale to nie jest jego główny cel. Rozważałbym Python lub Ruby, gdybym miał w szczególności wymóg dynamicznego języka.

Krótko mówiąc, naucz się naprawdę dobrze Sed i Awk, a także wszystkich innych dodatków, które pochodzą z Twoim gustem * nix (Wszystkie wbudowane Bash, grep, tr i tak dalej). Jeśli interesuje Cię przetwarzanie plików tekstowych, już używasz właściwych rzeczy.

Eric Smith
źródło
2

Możesz używać Pythona zamiast bash z ShellPy biblioteką .

Oto przykład, który pobiera awatar użytkownika Python z Github:

import json
import os
import tempfile

# get the api answer with curl
answer = `curl https://api.github.com/users/python
# syntactic sugar for checking returncode of executed process for zero
if answer:
    answer_json = json.loads(answer.stdout)
    avatar_url = answer_json['avatar_url']

    destination = os.path.join(tempfile.gettempdir(), 'python.png')

    # execute curl once again, this time to get the image
    result = `curl {avatar_url} > {destination}
    if result:
        # if there were no problems show the file
        p`ls -l {destination}
    else:
        print('Failed to download avatar')

    print('Avatar downloaded')
else:
    print('Failed to access github api')

Jak widać, wszystkie wyrażenia wewnątrz poważnego symbolu akcentu (`) są wykonywane w powłoce. A w kodzie Python można przechwytywać wyniki tego wykonania i wykonywać na nim działania. Na przykład:

log = `git log --pretty=oneline --grep='Create'

Ten wiersz najpierw zostanie wykonany git log --pretty=oneline --grep='Create'w powłoce, a następnie przypisze wynik do zmiennej log. Wynik ma następujące właściwości:

stdout całego tekstu z stdout wykonanego procesu

stderr cały tekst z stderr wykonanego procesu

kod powrotu kod powrotu wykonania

To jest ogólny przegląd biblioteki, bardziej szczegółowy opis z przykładami można znaleźć tutaj .

Alexander Ponomarev
źródło
1

Jeśli manipulowanie plikiem tekstowym zwykle odbywa się jednorazowo, prawdopodobnie w wierszu poleceń powłoki, nie uzyskasz nic lepszego od Pythona.

Z drugiej strony, jeśli zwykle musisz wykonywać to samo (lub podobne) zadanie w kółko i musisz do tego pisać swoje skrypty, to Python jest świetny - i możesz łatwo tworzyć własne biblioteki (możesz to zrobić to również ze skryptami powłoki, ale jest to bardziej kłopotliwe).

Bardzo prosty przykład na poznanie.

import popen2
stdout_text, stdin_text=popen2.popen2("your-shell-command-here")
for line in stdout_text:
  if line.startswith("#"):
    pass
  else
    jobID=int(line.split(",")[0].split()[1].lstrip("<").rstrip(">"))
    # do something with jobID

Sprawdź także sys i moduł getopt, są to pierwsze potrzebne.

Davide
źródło
1

Opublikowałem pakiet na PyPI: ez .
Użyj, pip install ezaby go zainstalować.

Ma spakowane typowe polecenia w powłoce i ładnie moja biblioteka lib używa zasadniczo tej samej składni co shell. np. cp (źródło, miejsce docelowe) może obsługiwać zarówno plik, jak i folder! (otoki shutil.copy shutil.copytree i decyduje, kiedy użyć). Co więcej, może wspierać wektoryzację jak R!

Kolejny przykład: brak os.walk, użyj fls (ścieżka, wyrażenie regularne), aby rekurencyjnie znajdować pliki i filtrować za pomocą wyrażeń regularnych i zwraca listę plików z pełną ścieżką lub bez niej

Ostatni przykład: możesz je połączyć, aby napisać bardzo proste skrypty:
files = fls('.','py$'); cp(files, myDir)

Zdecydowanie sprawdź to! Napisanie / ulepszenie mnie kosztowało mnie setki godzin!

Jerry T.
źródło
1
Wygląda interesująco, ale nie mogę przebić się przez niesformatowane dokumenty na pypi.python.org/pypi/ez , przepraszam ...
Greg Dubicki