Marcel – Um Shell Mais Moderno para Linux
Marcel é uma nova concha. É semelhante aos shells tradicionais em muitos aspectos, mas faz algumas coisas de maneira diferente:
- Piping: Todos os shells usam pipes para enviar um texto da saída de um comando para a entrada de outro. Marcel canaliza dados estruturados em vez de strings.
- Python: Marcel é implementado em Python e expõe o Python de diversas maneiras. Se você precisar de um pouco de lógica em seus comandos, marcel permite expressá-la em Python.
- Scripting: Marcel adota uma abordagem incomum para scripts. Você pode, é claro, simplesmente escrever uma sequência de comandos do Marcel em um arquivo de texto e executá-los. Mas Marcel também fornece uma API na forma de um módulo Python. Você pode importar este módulo para executar scripts Python de uma maneira muito mais conveniente do que é possível com Python simples.
Marcel é licenciado sob GPLv3.
Instalando Marcel Modern Shell no Linux
Marcel requer Python 3.6 ou posterior. Ele foi desenvolvido e testado em Linux e funciona principalmente em macOS. (Se você quiser ajudar a migrar para o Windows ou corrigir as deficiências do macOS, entre em contato.)
Para instalar marcel para seu próprio uso:
python3 -m pip install marcel
Ou se você deseja instalar para todos os usuários (por exemplo, para /usr/local
):
sudo python3 -m pip install --prefix /usr/local marcel
Depois de instalar o marcel, verifique se ele está funcionando executando o comando marcel e, em seguida, no prompt do marcel, execute a versão comando:
marcel
Personalização de Marcel Shell
Você pode personalizar marcel no arquivo ~/.marcel.py
, que é lido na inicialização (e relido quando modificado). Como você pode perceber pelo nome do arquivo, a customização do marcel é feita em Python.
Uma coisa que você provavelmente deseja fazer é personalizar o prompt. Para fazer isso, você atribui uma lista à variável PROMPT. Por exemplo, se você deseja que seu prompt seja o diretório atual, impresso em verde, seguido de >
impresso em azul:
PROMPT = [
Color(0, 4, 0),
lambda: PWD,
Color(0, 2, 5),
'> '
]
O prompt resultante é assim:
Isso substitui a configuração inescrutável do PS1
que você precisaria fazer no bash. Color(0, 4, 0) especifica verde, (os argumentos são valores RGB, no intervalo 0-5). PWD é a variável de ambiente que representa seu diretório atual e prefixar esta variável com lambda:
gera uma função, avaliada cada vez que o prompt é exibido.
O ~/.marcel.py
também pode importar módulos Python. Por exemplo, se você quiser usar as funções do módulo matemático em seus comandos marcel:
from math import *
Depois de fazer isso, você pode consultar os símbolos desse módulo, por exemplo. pi
:
Observe que pi
está entre parênteses. Em geral, marcel usa parênteses para delimitar expressões Python. Portanto (pi)
avalia a expressão Python que recupera o valor da variável pi. Você também pode acessar variáveis de ambiente tradicionais dessa forma, por exemplo. (USER) e (HOME), ou qualquer expressão Python válida que dependa de símbolos no namespace de marcel.
E você pode, claro, definir seus próprios símbolos. Por exemplo, se você colocar esta definição de função em ~/.marcel.py
:
def factorial(n):
f = 1
for i in range(1, n + 1):
f *= i
return f
então você pode usar a função fatorial na linha de comando, por exemplo.
Exemplos de Marcel Shell
Aqui, aprenderemos alguns exemplos de comandos no shell marcel.
Encontre tamanhos de arquivo por extensão
Explore o diretório atual recursivamente, agrupe os arquivos por extensão (por exemplo, .txt
, .py
e assim por diante) e calcule o tamanho total do arquivo para cada grupo.
Você pode fazer isso no Marcel da seguinte maneira:
O operador ls produz um fluxo de objetos File (-fr
significa visitar diretórios recursivamente e retornar apenas arquivos).
Os objetos Arquivo são canalizados para o próximo comando, map. O map especifica uma função Python, entre parênteses externos, que mapeia cada arquivo para uma tupla contendo a extensão do arquivo e seu tamanho. (Marcel permite que a palavra-chave lambda seja omitida.)
O operador vermelho (reduzir) agrupa pela primeira parte da tupla (extensão) e então soma os tamanhos dentro de cada grupo. O resultado é classificado por extensão.
Host Executáveis e Marcel Pipeline
Pipelines podem conter uma mistura de operadores marcel e executáveis de host. Os operadores canalizam objetos, mas nos limites do operador/executável, marcel canaliza strings.
Por exemplo, este comando combina operadores e executáveis e lista os nomes de usuário dos usuários cujo shell é /bin/bash
.
cat /etc/passwd \
| map (line: line.split(':')) \
| select (*line: line[-1] == '/bin/bash') \
| map (*line: line[0]) \
| xargs echo
cat é um executável do Linux. Ele lê /etc/passwd e marcel canaliza seu conteúdo downstream para o mapa do operador marcel.
O argumento entre parênteses para mapear é uma função Python que divide as linhas nos separadores :
, produzindo 7 tuplas. Um select é um operador marcel cujo argumento é uma função Python que identifica as tuplas nas quais o último campo é /bin/bash.
O próximo operador, outro mapa, mantém o campo de nome de usuário de cada tupla de entrada. Finalmente, xargs echo combina os nomes de usuário recebidos em uma única linha, que é impressa em stdout.
Scripts em Marcel Shell
Embora Python às vezes seja considerado uma linguagem de script, na verdade ele não funciona bem para esse propósito. O problema é que executar comandos shell e outros executáveis do Python é complicado. Você pode usar os.system()
, que é simples, mas muitas vezes inadequado para lidar com stdin, stdout e stderr. subprocess.Popen()
é mais poderoso, mas mais complexo de usar.
A abordagem de Marcel é fornecer um módulo que integre os operadores Marcel com os recursos da linguagem Python. Para revisitar um exemplo anterior, aqui está o código Python para calcular a soma dos tamanhos de arquivo por extensão:
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})
Os comandos shell são os mesmos de antes, exceto pelas convenções sintáticas. Então ls -fr
se transforma em ls(file=True, recursive=True). O mapa e os operadores vermelhos também estão lá, conectados por tubos, como na versão shell. Todo o comando shell (ls… red) produz um iterador Python para que o comando possa ser usado com um loop for do Python.
Acesso ao banco de dados com Marcel Shell
Você pode integrar o acesso ao banco de dados com pipelines do Marcel. Primeiro, você precisa configurar o acesso ao banco de dados no arquivo de configuração, ~/.marcel.py
, por exemplo.
define_db(name='jao',
driver='psycopg2',
dbname='acme',
user='jao')
DB_DEFAULT = 'jao'
Isso configura o acesso a um banco de dados Postgres chamado acme, usando o driver psycopg2. As conexões do marcel serão feitas usando o usuário jao, e o perfil do banco de dados é denominado jao. (DB_DEFAULT especifica o perfil do banco de dados jao como aquele a ser usado se nenhum perfil for especificado.) Com esta configuração feita, o banco de dados agora pode ser consultado usando o operador sql, por exemplo.
sql 'select part_name, quantity from part where quantity < 10' \
| out --csv –-file ~/reorder.csv
Este comando consulta uma tabela chamada part e despeja o resultado da consulta no arquivo ~/reorder.csv
, no formato CSV.
Acesso Remoto com Marcel Shell
Da mesma forma que o acesso ao banco de dados, o acesso remoto pode ser configurado em ~/.marcel.py
. Por exemplo, isso configura um cluster de 4 nós:
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'])
O cluster pode ser identificado como um laboratório nos comandos marcel. Os parâmetros de usuário e identidade especificam informações de login e o parâmetro host especifica os endereços IP dos nós no cluster.
Depois que o cluster estiver configurado, todos os nós poderão ser operados de uma só vez. Por exemplo, para obter uma lista de pids de processos e linhas de comando no cluster:
@lab [ps | map (proc: (proc.pid, proc.commandline))]
Isso retorna um fluxo de tuplas (endereço IP, PID, linha de comando).
Para mais informações visite:
- https://www.marceltheshell.org/
- https://github.com/geophile/marcel
Marcel é bastante novo e está em desenvolvimento ativo. Entre em contato se quiser ajudar.