Marcel - Eng méi modern Shell fir Linux


De Marcel ass eng nei Schuel. Et ass op ville Weeër ähnlech wéi traditionell Muschelen, awer et mécht e puer Saachen anescht:

  • Piping: All Shells benotze Päifen fir en Text vum Ausgang vun engem Kommando op den Input vun engem aneren ze schécken. Marcel Päif strukturéiert Daten amplaz Strings.
  • Python: De Marcel gëtt am Python implementéiert, an exponéiert Python op e puer Weeër. Wann Dir e bësse Logik an Äre Kommandoen braucht, erlaabt de Marcel Iech et am Python auszedrécken.
  • Skript: De Marcel hëlt eng ongewéinlech Approche zum Skript. Dir kënnt natierlech einfach eng Sequenz vu Marcel Kommandoen an enger Textdatei schreiwen an se ausféieren. Mee Marcel bitt och eng API a Form vun engem Python Modul. Dir kënnt dëse Modul importéieren fir Python Scripting op eng vill méi bequem Manéier ze maachen wéi et méiglech ass mat engem einfachen Python.

De Marcel ass ënner GPLv3 lizenzéiert.

Installéiere vum Marcel Modern Shell op Linux

Marcel verlaangt Python 3.6 oder méi spéit. Et gouf op Linux entwéckelt a getest, an et funktionnéiert meeschtens op macOS. (Wann Dir hëllefe wëllt op Windows ze portéieren oder d'MacOS Mängel ze fixéieren, kontaktéiert Iech.)

Fir de Marcel fir Ären eegene Gebrauch z'installéieren:

# python3 -m pip install marcel

Oder wann Dir fir all Benotzer installéiere wëllt (z.B. op /usr/local):

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

Wann Dir de marcel installéiert hutt, kontrolléiert datt et funktionnéiert andeems Dir de Kommando marcel leeft, an dann op der marcel-Prompt, fuert de Versiounskommando:

$ marcel

Personnalisatioun vum Marcel Shell

Dir kënnt de Marcel an der Datei ~/.marcel.py personaliséieren, déi beim Startup gelies gëtt (an nach eng Kéier gelies gëtt wann et geännert gëtt). Wéi Dir aus dem Dateinumm kënnt soen, gëtt d'Personaliséierung vum Marcel am Python gemaach.

Eng Saach déi Dir wahrscheinlech maache wëllt ass d'Prompt ze personaliséieren. Fir dëst ze maachen, gitt Dir eng Lëscht un der PROMPT Variabel. Zum Beispill, wann Dir wëllt datt Är Prompt den aktuellen Verzeechnes ass, a gréng gedréckt, gefollegt vun > a blo gedréckt:

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

Déi resultéierend Prompt gesäit esou aus:

Dëst ersetzt déi onkloerbar PS1 Konfiguratioun déi Dir am Bash maache musst. Faarf (0, 4, 0) spezifizéiert gréng, (d'Argumenter sinn RGB Wäerter, am Beräich 0-5). PWD ass d'Ëmfeldsvariabel, déi Ären aktuellen Verzeechnes representéiert an dës Variabel mat lambda: prefixéiert generéiert eng Funktioun, déi all Kéier wann d'Prompt ugewise gëtt, evaluéiert gëtt.

De ~/.marcel.py kann och Python Moduler importéieren. Zum Beispill, wann Dir d'Funktioune vum Mathematikmodul an Äre Marcel Kommandoen benotze wëllt:

from math import *

Wann Dir dëst gemaach hutt, kënnt Dir op Symboler aus deem Modul bezéien, z.B. pi:

Notéiert datt pi parenthesized ass. Allgemeng benotzt de Marcel Klammern fir Python Ausdréck ze delimitéieren. Also (pi) evaluéiert de Python Ausdrock deen de Wäert vun der Variabel pi zréckhëlt. Dir kënnt och op dës Manéier traditionell Ëmfeldvariablen zougräifen, z.B. (USER) an (HOME), oder all gëlteg Python Ausdrock, deen op Symboler am marcel Nummraum vertrauen.

An Dir kënnt natierlech Är eege Symboler definéieren. Zum Beispill, wann Dir dës Funktiounsdefinitioun an ~/.marcel.py setzt:

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

da kënnt Dir d'Factorial Funktioun op der Kommandozeil benotzen, z.B.

Marcel Shell Beispiller

Hei léiere mir e puer Beispiller vu Kommandoen an der Marcel Shell.

Entdeckt den aktuellen Verzeechnes rekursiv, gruppéiert d'Dateien no hirer Extensioun (zB .txt, .py an sou weider), a berechnen d'total Dateigréisst fir all Grupp.

Dir kënnt dat am Marcel maachen wéi follegt:

Den ls Bedreiwer produzéiert e Stroum vu Dateiobjekter, (-fr bedeit d'Verzeechnes rekursiv besichen, an nëmmen Dateien zréckginn).

D'Dateiobjekter ginn op de nächste Kommando, Kaart. D'Kaart spezifizéiert eng Python-Funktioun, an den äusserste Klammern, déi all Datei op en Tupel mapéiert mat der Dateiextensioun, an hir Gréisst. (Marcel erlaabt datt d'Lambda Schlësselwuert ewechgelooss gëtt.)

De roude (reduzéieren) Bedreiwer, Gruppen duerch den éischten Deel vun der tuple (Erweiderung) an summéiert dann d'Gréissten bannent all Grupp. D'Resultat gëtt no Verlängerung zortéiert.

Pipelines kënnen eng Mëschung aus Marcel Bedreiwer a Host ausführbar enthalen. Bedreiwer Päif Objete, mee um Bedreiwer/ausféierbar Grenzen, Marcel Päifen Strings amplaz.

Zum Beispill kombinéiert dëse Kommando Betreiber an ausführbar a lëscht d'Benotzernimm vun de Benotzer deenen hir Shell /bin/bash ass.

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

cat ass e Linux ausféierbar. Et liest /etc/passwd, a Marcel päift säin Inhalt downstream op d'Marcel Bedreiwer Kaart.

D'Klammern Argument fir ze mapen ass eng Python Funktioun déi d'Linnen an de : Separatoren opdeelt, wat 7-Tupelen erginn. E Select ass e Marcel Bedreiwer deem säin Argument eng Python Funktioun ass, déi dës Tuple identifizéiert an deenen dat lescht Feld /bin/bash ass.

Déi nächst Bedreiwer, eng aner Kaart hält de Benotzernumm Feld vun all Input Tuple. Schlussendlech kombinéiert xargs Echo déi erakommen Benotzernimm an eng eenzeg Linn, déi op stdout gedréckt gëtt.

Scripting am Marcel Shell

Iwwerdeems Python heiansdo als eng Skriptsprooch ugesi gëtt, funktionnéiert et eigentlech net gutt fir dësen Zweck. De Problem ass datt d'Shellbefehle lafen, an aner ausführbar aus Python ass ëmständlech. Dir kënnt os.system() benotzen, wat einfach ass awer dacks net genuch fir mat stdin, stdout a stderr ze handelen. subprocess.Popen() ass méi mächteg awer méi komplex ze benotzen.

Dem Marcel seng Approche ass e Modul ze bidden deen de Marcel Bedreiwer mat de Python Sproochefeatures integréiert. Fir e fréiert Beispill ze besichen, hei ass de Python Code fir d'Zomm vun de Dateigréissten duerch Extensioun ze berechnen:

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})

D'Shellbefehle sinn déiselwecht wéi virdrun, ausser fir syntaktesch Konventiounen. Also ls -fr gëtt an ls(Datei=Wou, rekursiv=Wou). D'Kaart a roude Bedreiwer sinn och do, verbonne mat Päifen, wéi an der Shell Versioun. De ganze Shell Kommando (ls ... rout) gëtt e Python Iterator sou datt de Kommando mat Python's fir eng Loop benotzt ka ginn.

Datebank Zougang mam Marcel Shell

Dir kënnt Datebank Zougang mat Marcel Pipelines integréieren. Als éischt musst Dir d'Datebankzougang an der Configuratiounsdatei konfiguréieren, ~/.marcel.py, z.B.

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

DB_DEFAULT = 'jao'

Dëst konfiguréiert den Zougang zu enger Postgres Datebank mam Numm acme, mam psycopg2 Chauffer. D'Verbindunge vu Marcel ginn mam jao Benotzer gemaach, an den Datebankprofil gëtt jao genannt. (DB_DEFAULT spezifizéiert de jao-Datebankprofil als deen, dee benotzt gëtt, wa kee Profil uginn ass.) Mat dëser Konfiguratioun kann d'Datebank elo mam sql-Bedreiwer ugefrot ginn, z.B.

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

Dëse Kommando freet en Dësch mam Numm Deel, an dumpt d'Ufroresultat an d'Datei ~/reorder.csv, am CSV-Format.

Fernzougang mam Marcel Shell

Ähnlech wéi d'Datebankzougang, kann de Fernzougang an ~/.marcel.py konfiguréiert ginn. Zum Beispill konfiguréiert dëst e 4-Node Cluster:

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'])

De Stärekoup kann als Labo a Marcel Kommandoen identifizéiert ginn. D'Benotzer- an d'Identitéitsparameter spezifizéieren Umeldungsinformatioun, an den Hostparameter spezifizéiert d'IP Adressen vun den Noden am Cluster.

Wann de Stärekoup konfiguréiert ass, kënnen all Node gläichzäiteg operéiert ginn. Zum Beispill, fir eng Lëscht vu Prozesspids a Kommandozeilen iwwer de Cluster ze kréien:

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

Dëst gëtt e Stroum vun (IP Adress, PID, Kommandozeil) Tuples zréck.

Fir méi Informatiounen besicht:

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

De Marcel ass zimlech nei an ënner aktiv Entwécklung. Kontaktéiert Iech wann Dir hëllefe wëllt.