Recherche de site Web

Marcel - Un shell plus moderne pour Linux


Marcel est une nouvelle coquille. Il ressemble aux coquilles traditionnelles à bien des égards, mais il fait certaines choses différemment :

  • Piping : tous les shells utilisent des tuyaux pour envoyer un texte de la sortie d'une commande à l'entrée d'une autre. Marcel dirige des données structurées au lieu de chaînes.
  • Python : Marcel est implémenté en Python et expose Python de plusieurs manières. Si vous avez besoin d'un peu de logique dans vos commandes, marcel vous permet de l'exprimer en Python.
  • Scripting : Marcel adopte une approche inhabituelle du script. Vous pouvez bien sûr simplement écrire une séquence de commandes marcel dans un fichier texte et les exécuter. Mais Marcel propose également une API sous la forme d'un module Python. Vous pouvez importer ce module pour effectuer des scripts Python d'une manière beaucoup plus pratique qu'avec Python simple.

Marcel est sous licence GPLv3.

Installation de Marcel Modern Shell sous Linux

Marcel nécessite Python 3.6 ou version ultérieure. Il a été développé et testé sous Linux et fonctionne principalement sous macOS. (Si vous souhaitez contribuer au portage vers Windows ou corriger les déficiences de macOS, contactez-nous.)

Pour installer marcel pour votre propre usage :

python3 -m pip install marcel

Ou si vous souhaitez installer pour tous les utilisateurs (par exemple, sur /usr/local) :

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

Une fois que vous avez installé marcel, vérifiez qu'il fonctionne en exécutant la commande marcel, puis à l'invite marcel, exécutez la version commande :

marcel

Personnalisation de Marcel Shell

Vous pouvez personnaliser marcel dans le fichier ~/.marcel.py, qui est lu au démarrage, (et relu une fois modifié). Comme vous pouvez le constater d'après le nom du fichier, la personnalisation de Marcel se fait en Python.

Une chose que vous souhaiterez probablement faire est de personnaliser l'invite. Pour ce faire, vous affectez une liste à la variable PROMPT. Par exemple, si vous souhaitez que votre invite soit le répertoire actuel, imprimé en vert, suivi de > imprimé en bleu :

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

L'invite résultante ressemble à ceci :

Cela remplace la configuration impénétrable PS1 que vous auriez besoin de faire dans bash. Color(0, 4, 0) spécifie le vert (les arguments sont des valeurs RVB, comprises entre 0 et 5. fort>). PWD est la variable d'environnement représentant votre répertoire actuel et préfixer cette variable avec lambda : génère une fonction, évaluée à chaque fois que l'invite est affichée.

Le ~/.marcel.py peut également importer des modules Python. Par exemple, si vous souhaitez utiliser les fonctions du module math dans vos commandes marcel :

from math import *

Une fois que vous avez fait cela, vous pouvez vous référer aux symboles de ce module, par ex. pi :

Notez que pi est entre parenthèses. En général, marcel utilise des parenthèses pour délimiter les expressions Python. Ainsi (pi) évalue l'expression Python qui récupère la valeur de la variable pi. Vous pouvez également accéder aux variables d'environnement traditionnelles de cette manière, par ex. (USER) et (HOME), ou toute expression Python valide reposant sur des symboles dans l'espace de noms de Marcel.

Et vous pouvez bien entendu définir vos propres symboles. Par exemple, si vous mettez cette définition de fonction dans ~/.marcel.py :

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

alors vous pouvez utiliser la fonction factorielle sur la ligne de commande, par ex.

Exemples de Marcel Shell

Ici, nous allons apprendre quelques exemples de commandes dans le shell marcel.

Rechercher les tailles de fichiers par extension

Explorez le répertoire actuel de manière récursive, regroupez les fichiers par leur extension (par exemple .txt, .py et ainsi de suite) et calculez la taille totale du fichier pour chaque groupe.

Vous pouvez le faire dans Marcel comme suit :

L'opérateur ls produit un flux d'objets File (-fr signifie visiter les répertoires de manière récursive et renvoyer uniquement les fichiers).

Les objets File sont redirigés vers la commande suivante, map. La map spécifie une fonction Python, dans les parenthèses les plus extérieures, qui mappe chaque fichier à un tuple contenant l'extension du fichier et sa taille. (Marcel permet d'omettre le mot-clé lambda.)

L'opérateur rouge (réduire), regroupe par la première partie du tuple (extension), puis résume les tailles au sein de chaque groupe. Le résultat est trié par extension.

Exécutables hôtes et pipeline Marcel

Les Pipelines peuvent contenir un mélange d'opérateurs Marcel et d'exécutables hôtes. Les opérateurs dirigent les objets, mais aux limites opérateur/exécutable, Marcel dirige les chaînes à la place.

Par exemple, cette commande combine des opérateurs et des exécutables et répertorie les noms d'utilisateurs dont le shell est /bin/bash.

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

cat est un exécutable Linux. Il lit /etc/passwd et marcel redirige son contenu vers la carte de l'opérateur marcel.

L'argument entre parenthèses à mapper est une fonction Python qui divise les lignes au niveau des séparateurs :, produisant 7 tuples. Un select est un opérateur marcel dont l'argument est une fonction Python identifiant les tuples dans lesquels le dernier champ est /bin/bash.

L'opérateur suivant, une autre carte conserve le champ de nom d'utilisateur de chaque tuple d'entrée. Enfin, xargs echo combine les noms d'utilisateur entrants en une seule ligne, qui est imprimée sur la sortie standard.

Scripts dans Marcel Shell

Bien que Python soit parfois considéré comme un langage de script, il ne fonctionne pas vraiment bien à cette fin. Le problème est que l’exécution de commandes shell et d’autres exécutables à partir de Python est fastidieuse. Vous pouvez utiliser os.system(), qui est simple mais souvent inadapté pour gérer stdin, stdout et stderr. subprocess.Popen() est plus puissant mais plus complexe à utiliser.

L'approche de Marcel consiste à fournir un module qui intègre les opérateurs Marcel aux fonctionnalités du langage Python. Pour revenir sur un exemple précédent, voici le code Python permettant de calculer la somme des tailles de fichiers par extension :

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

Les commandes shell sont les mêmes qu'auparavant, à l'exception des conventions syntaxiques. Donc ls -fr se transforme en ls(file=True, recursive=True). Les opérateurs map et rouge sont là aussi, connectés à des tuyaux, comme dans la version shell. L'intégralité de la commande shell (ls … red) génère un itérateur Python afin que la commande puisse être utilisée avec Python pour une boucle.

Accès aux bases de données avec Marcel Shell

Vous pouvez intégrer l'accès à la base de données avec les pipelines Marcel. Tout d'abord, vous devez configurer l'accès à la base de données dans le fichier de configuration, ~/.marcel.py, par exemple.

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

DB_DEFAULT = 'jao'

Ceci configure l'accès à une base de données Postgres nommée acme, à l'aide du pilote psycopg2. Les connexions depuis Marcel seront établies à l'aide de l'utilisateur jao et le profil de base de données est nommé jao. (DB_DEFAULT spécifie le profil de base de données jao comme celui à utiliser si aucun profil n'est spécifié.) Une fois cette configuration effectuée, la base de données peut maintenant être interrogée à l'aide de l'opérateur sql, par ex.

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

Cette commande interroge une table nommée part et transfère le résultat de la requête dans le fichier ~/reorder.csv, au format CSV.

Accès à distance avec Marcel Shell

De la même manière que l'accès à la base de données, l'accès à distance peut être configuré dans ~/.marcel.py. Par exemple, ceci configure un cluster à 4 nœuds :

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

Le cluster peut être identifié comme un laboratoire dans les commandes Marcel. Les paramètres utilisateur et d'identité spécifient les informations de connexion et le paramètre host spécifie les adresses IP des nœuds du cluster.

Une fois le cluster configuré, tous les nœuds peuvent être exploités en même temps. Par exemple, pour obtenir une liste des pids de processus et des lignes de commande dans le cluster :

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

Cela renvoie un flux de tuples (adresse IP, PID, ligne de commande).

Pour plus d'informations, visitez:

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

Marcel est assez nouveau et en cours de développement actif. Contactez-nous si vous souhaitez aider.