Wyszukiwanie w witrynie

Marcel — bardziej nowoczesna powłoka dla systemu Linux


Marcel to nowa powłoka. Pod wieloma względami jest podobny do tradycyjnych powłok, ale robi kilka rzeczy inaczej:

  • Piping: wszystkie powłoki używają potoków do wysyłania tekstu z wyjścia jednego polecenia na wejście innego. Marcel przesyła uporządkowane dane zamiast ciągów znaków.
  • Python: Marcel jest zaimplementowany w Pythonie i udostępnia go na wiele sposobów. Jeśli potrzebujesz odrobiny logiki w swoich poleceniach, marcel pozwala wyrazić to w Pythonie.
  • Skrypty: Marcel ma niezwykłe podejście do pisania skryptów. Możesz oczywiście po prostu zapisać sekwencję poleceń Marcel w pliku tekstowym i wykonać je. Ale Marcel udostępnia również API w postaci modułu Pythona. Możesz zaimportować ten moduł, aby wykonywać skrypty w języku Python w znacznie wygodniejszy sposób niż jest to możliwe w przypadku zwykłego języka Python.

Marcel jest objęty licencją GPLv3.

Instalowanie Marcela Modern Shell w systemie Linux

Marcel wymaga Pythona 3.6 lub nowszego. Został opracowany i przetestowany na Linuksie i działa głównie na macOS. (Jeśli chcesz pomóc w przeniesieniu do Windows lub naprawić braki w macOS, skontaktuj się z nami).

Aby zainstalować marcel na własny użytek:

python3 -m pip install marcel

Lub jeśli chcesz zainstalować dla wszystkich użytkowników (np. w /usr/local):

sudo python3 -m pip install --prefix /usr/local marcel

Po zainstalowaniu marcel sprawdź, czy działa, wydając polecenie marcel, a następnie po wyświetleniu monitu marcel uruchom wersję polecenie:

marcel

Personalizacja Marcela Shella

Możesz dostosować marcel w pliku ~/.marcel.py, który jest odczytywany przy uruchomieniu (i ponownie odczytywany po modyfikacji). Jak widać z nazwy pliku, dostosowywanie marcela odbywa się w Pythonie.

Jedną z rzeczy, które prawdopodobnie chcesz zrobić, jest dostosowanie monitu. Aby to zrobić, przypisujesz listę do zmiennej PROMPT. Na przykład, jeśli chcesz, aby monitem był bieżący katalog wydrukowany na zielono, a po nim > wydrukowany na niebiesko:

PROMPT = [
    Color(0, 4, 0),
    lambda: PWD,
    Color(0, 2, 5),
    '> '
]

Wynikowy monit wygląda następująco:

Zastępuje to nieodgadnioną konfigurację PS1, którą musiałbyś wykonać w bashu. Kolor(0, 4, 0) określa kolor zielony, (argumentami są wartości RGB z zakresu 0-5 mocny>). PWD to zmienna środowiskowa reprezentująca bieżący katalog i poprzedzona tą zmienną lambda: generuje funkcję, ocenianą za każdym razem, gdy wyświetlany jest monit.

~/.marcel.py może także importować moduły Pythona. Np. jeśli chcesz używać funkcji modułu matematycznego w swoich poleceniach marcel:

from math import *

Kiedy już to zrobisz, możesz odwoływać się do symboli z tego modułu, np. pi:

Zwróć uwagę, że pi jest ujęte w nawiasy. Ogólnie rzecz biorąc, marcel używa nawiasów do oddzielania wyrażeń Pythona. Zatem (pi) ocenia wyrażenie Pythona, które pobiera wartość zmiennej pi. W ten sposób można także uzyskać dostęp do tradycyjnych zmiennych środowiskowych, np. (USER) i (HOME) lub dowolne prawidłowe wyrażenie Pythona opierające się na symbolach w przestrzeni nazw Marcela.

Możesz oczywiście zdefiniować własne symbole. Na przykład, jeśli umieścisz tę definicję funkcji w ~/.marcel.py:

def factorial(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

następnie możesz użyć funkcji silni w wierszu poleceń, np.

Przykłady Marcela Shella

Tutaj nauczymy się kilku przykładów poleceń w powłoce marcel.

Znajdź rozmiary plików według rozszerzenia

Przeglądaj bieżący katalog rekurencyjnie, grupuj pliki według ich rozszerzenia (np. .txt, .py itd.) i obliczaj całkowity rozmiar plików dla każdej grupy.

Możesz to zrobić w marcelu w następujący sposób:

Operator ls tworzy strumień obiektów File (-fr oznacza rekurencyjne odwiedzanie katalogów i zwracanie tylko plików).

Obiekty Plik są przesyłane do następnego polecenia, map. mapa określa w skrajnych nawiasach funkcję Pythona, która mapuje każdy plik na krotkę zawierającą rozszerzenie pliku i jego rozmiar. (Marcel pozwala na pominięcie słowa kluczowego lambda.)

Operator czerwony (zmniejsz) grupuje według pierwszej części krotki (rozszerzenie), a następnie sumuje rozmiary w każdej grupie. Wynik jest posortowany według rozszerzenia.

Pliki wykonywalne hosta i potok Marcela

Potoki mogą zawierać kombinację operatorów marcel i plików wykonywalnych hosta. Operatory potokują obiekty, ale na granicy operatora/pliku wykonywalnego zamiast tego marcel potokuje ciągi znaków.

Na przykład to polecenie łączy operatory i pliki wykonywalne oraz wyświetla listę nazw użytkowników, których powłoka to /bin/bash.

cat /etc/passwd \
| map (line: line.split(':')) \
| select (*line: line[-1] == '/bin/bash') \
| map (*line: line[0]) \
| xargs echo

cat jest plikiem wykonywalnym systemu Linux. Odczytuje /etc/passwd i marcel przesyła jego zawartość w dół do mapy operatora marcel.

Argument w nawiasach służący do mapowania to funkcja Pythona, która dzieli linie w miejscu separatorów :, uzyskując 7 krotek. select to operator marcel, którego argumentem jest funkcja Pythona identyfikująca te krotki, w których ostatnim polem jest /bin/bash.

Następny operator, kolejna mapa, przechowuje pole nazwy użytkownika każdej krotki wejściowej. Na koniec xargs echo łączy przychodzące nazwy użytkowników w jedną linię, która jest wypisywany na standardowe wyjście.

Skrypty w Marcel Shell

Chociaż Python jest czasami uważany za język skryptowy, w rzeczywistości nie sprawdza się dobrze w tym celu. Problem polega na tym, że uruchamianie poleceń powłoki i innych plików wykonywalnych w Pythonie jest kłopotliwe. Możesz użyć funkcji os.system(), która jest prosta, ale często nieodpowiednia do obsługi stdin, stdout i stderr. subprocess.Popen() jest potężniejszy, ale bardziej skomplikowany w użyciu.

Podejście Marcela polega na dostarczeniu modułu, który integruje operatory marcel z funkcjami języka Python. Aby powrócić do wcześniejszego przykładu, oto kod Pythona służący do obliczania sumy rozmiarów plików według rozszerzenia:

from marcel.api import *

for ext, size in (ls(file=True, recursive=True)
                  | map(lambda f: (f.suffix, f.size))
                  | red('.', '+')):
    print(f'{ext}: {size})

Polecenia powłoki są takie same jak poprzednio, z wyjątkiem konwencji składniowych. Zatem ls -fr zmienia się na ls(file=True, recursive=True). Znajdują się tam także mapa i czerwoni operatorzy, połączeni rurami, tak jak w wersji powłoki. Całe polecenie powłoki (ls … red) udostępnia iterator Pythona, dzięki czemu polecenia można używać z pętlą for Pythona.

Dostęp do bazy danych za pomocą Marcel Shell

Dostęp do bazy danych można zintegrować z potokami Marcel. Najpierw musisz skonfigurować dostęp do bazy danych w pliku konfiguracyjnym ~/.marcel.py, np.

define_db(name='jao',
          driver='psycopg2',
          dbname='acme',
          user='jao')

DB_DEFAULT = 'jao'

Konfiguruje to dostęp do bazy danych Postgres o nazwie acme przy użyciu sterownika psycopg2. Połączenia z marcelem będą nawiązywane przy użyciu użytkownika jao, a profil bazy danych będzie nosił nazwę jao. (DB_DEFAULT określa profil bazy danych jao jako ten, który będzie używany, jeśli nie określono żadnego profilu.) Po wykonaniu tej konfiguracji można teraz odpytywać bazę danych za pomocą operatora sql, np.

sql 'select part_name, quantity from part where quantity < 10' \
| out --csv –-file ~/reorder.csv

To polecenie wysyła zapytanie do tabeli o nazwie part i zrzuca wynik zapytania do pliku ~/reorder.csv w formacie CSV.

Zdalny dostęp za pomocą Marcel Shell

Podobnie jak dostęp do bazy danych, dostęp zdalny można skonfigurować w ~/.marcel.py. Na przykład konfiguruje to klaster z 4 węzłami:

define_remote(name='lab',
              user='frankenstein',
              identity='/home/frankenstein/.ssh/id_rsa',
              host=['10.0.0.100', 
                    '10.0.0.101',
                    '10.0.0.102',
                    '10.0.0.103'])

Klaster można zidentyfikować jako laboratorium w poleceniach Marcel. Parametry użytkownika i tożsamości określają dane logowania, a parametr host określa adresy IP węzłów w klastrze.

Po skonfigurowaniu klastra można obsługiwać wszystkie węzły jednocześnie. Na przykład, aby uzyskać listę pidów procesów i wierszy poleceń w klastrze:

@lab [ps | map (proc: (proc.pid, proc.commandline))]

Zwraca strumień krotek (adres IP, PID, linia poleceń).

Po więcej informacji odwiedź:

  • https://www.marceltheshell.org/
  • https://github.com/geophile/marcel

Marcel jest całkiem nowym produktem i jest w fazie aktywnego rozwoju. Skontaktuj się, jeśli chcesz pomóc.