Marcel - Shell yang Lebih Modern untuk Linux


Marcel adalah cangkang baru. Dalam banyak hal, cangkang ini mirip dengan cangkang tradisional, namun fungsinya berbeda:

  • Piping: Semua shell menggunakan pipa untuk mengirim teks dari output satu perintah ke input perintah lainnya. Marcel menyalurkan data terstruktur, bukan string.
  • Python: Marcel diimplementasikan dengan Python, dan mengekspos Python dalam beberapa cara. Jika Anda memerlukan sedikit logika dalam perintah Anda, Marcel mengizinkan Anda mengekspresikannya dengan Python.
  • Pembuatan skrip: Marcel menggunakan pendekatan yang tidak biasa dalam pembuatan skrip. Anda tentu saja dapat menulis urutan perintah marcel dalam file teks dan menjalankannya. Namun Marcel juga menyediakan API berupa modul Python. Anda dapat mengimpor modul ini untuk melakukan skrip Python dengan cara yang jauh lebih nyaman dibandingkan dengan Python biasa.

Marcel dilisensikan di bawah GPLv3.

Menginstal Marcel Modern Shell di Linux

Marcel memerlukan Python 3.6 atau lebih baru. Ini telah dikembangkan dan diuji di Linux, dan sebagian besar berfungsi di macOS. (Jika Anda ingin membantu melakukan porting ke Windows, atau untuk memperbaiki kekurangan macOS, hubungi kami.)

Untuk memasang marcel untuk Anda gunakan sendiri:

python3 -m pip install marcel

Atau jika Anda ingin menginstal untuk semua pengguna (misalnya, ke /usr/local):

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

Setelah Anda menginstal marcel, periksa apakah itu berfungsi dengan menjalankan perintah marcel, lalu pada perintah marcel, jalankan versi perintah:

marcel

Kustomisasi Marcel Shell

Anda dapat menyesuaikan marcel di file ~/.marcel.py, yang dibaca saat startup, (dan dibaca ulang saat diubah). Seperti yang Anda ketahui dari nama filenya, kustomisasi marcel dilakukan dengan Python.

Satu hal yang mungkin ingin Anda lakukan adalah menyesuaikan prompt. Untuk melakukan hal ini, Anda menetapkan daftar ke variabel PROMPT. Misalnya, jika Anda ingin prompt Anda menjadi direktori saat ini, dicetak dengan warna hijau, diikuti dengan > yang dicetak dengan warna biru:

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

Prompt yang dihasilkan terlihat seperti ini:

Ini menggantikan konfigurasi PS1 yang tidak dapat dipahami yang perlu Anda lakukan di bash. Warna(0, 4, 0) menentukan hijau, (argumennya adalah nilai RGB, dalam rentang 0-5). PWD adalah variabel lingkungan yang mewakili direktori Anda saat ini dan mengawali variabel ini dengan lambda: akan menghasilkan fungsi, dievaluasi setiap kali perintah ditampilkan.

~/.marcel.py juga dapat mengimpor modul Python. Misalnya, jika Anda ingin menggunakan fungsi modul matematika dalam perintah marcel Anda:

from math import *

Setelah Anda selesai melakukannya, Anda dapat merujuk ke simbol dari modul itu, mis. pi:

Perhatikan bahwa pi diberi tanda kurung. Secara umum, marcel menggunakan tanda kurung untuk membatasi ekspresi Python. Jadi (pi) mengevaluasi ekspresi Python yang mengambil nilai variabel pi. Anda juga dapat mengakses variabel lingkungan tradisional dengan cara ini, mis. (USER) dan (HOME), atau ekspresi Python valid apa pun yang mengandalkan simbol di namespace marcel.

Dan tentu saja Anda dapat menentukan simbol Anda sendiri. Misalnya, jika Anda memasukkan definisi fungsi ini ke dalam ~/.marcel.py:

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

maka Anda dapat menggunakan fungsi faktorial pada baris perintah, mis.

Contoh Marcel Shell

Di sini, kita akan mempelajari beberapa contoh perintah di shell marcel.

Temukan Ukuran File berdasarkan Ekstensi

Jelajahi direktori saat ini secara rekursif, kelompokkan file berdasarkan ekstensinya (misalnya .txt, .py, dan seterusnya), dan hitung total ukuran file untuk setiap grup.

Anda dapat melakukan ini di marcel sebagai berikut:

Operator ls menghasilkan aliran objek File, (-fr berarti mengunjungi direktori secara rekursif, dan hanya mengembalikan file).

Objek File disalurkan ke perintah berikutnya, map. peta menentukan fungsi Python, dalam tanda kurung terluar, yang memetakan setiap file ke tupel yang berisi ekstensi file, dan ukurannya. (Marcel mengizinkan kata kunci lambda dihilangkan.)

Operator merah (pengurangan), mengelompokkan berdasarkan bagian pertama tuple (ekstensi) dan kemudian menjumlahkan ukuran dalam setiap grup. Hasilnya diurutkan berdasarkan ekstensi.

Host Executable dan Marcel Pipeline

Pipeline mungkin berisi campuran operator marcel dan executable host. Operator menyalurkan objek, tetapi pada batas operator/yang dapat dieksekusi, marcel menyalurkan string sebagai gantinya.

Misalnya, perintah ini menggabungkan operator dan executable serta mencantumkan nama pengguna pengguna yang shellnya adalah /bin/bash.

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

cat adalah Linux yang dapat dieksekusi. Bunyinya /etc/passwd, dan marcel menyalurkan isinya ke hilir ke peta operator marcel.

Argumen dalam tanda kurung untuk memetakan adalah fungsi Python yang membagi garis pada pemisah :, menghasilkan 7 tupel. pilih adalah operator marcel yang argumennya berupa fungsi Python yang mengidentifikasi tupel yang bidang terakhirnya adalah /bin/bash.

Operator berikutnya, peta lain menyimpan kolom nama pengguna dari setiap tupel masukan. Terakhir, xargs echo menggabungkan nama pengguna yang masuk ke dalam satu baris, yang dicetak ke stdout.

Pembuatan skrip di Marcel Shell

Meskipun Python terkadang dianggap sebagai bahasa skrip, sebenarnya bahasa ini tidak berfungsi dengan baik untuk tujuan tersebut. Masalahnya adalah menjalankan perintah shell, dan executable lainnya dari Python itu rumit. Anda dapat menggunakan os.system(), yang sederhana namun seringkali tidak memadai untuk menangani stdin, stdout, dan stderr. subprocess.Popen() lebih kuat namun lebih kompleks untuk digunakan.

Pendekatan Marcel adalah menyediakan modul yang mengintegrasikan operator marcel dengan fitur bahasa Python. Untuk melihat kembali contoh sebelumnya, berikut adalah kode Python untuk menghitung jumlah ukuran file berdasarkan ekstensi:

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

Perintah shell sama seperti sebelumnya, kecuali konvensi sintaksis. Jadi ls -fr berubah menjadi ls(file=True, recursive=True). Peta dan operator merah juga ada di sana, dihubungkan dengan pipa, seperti pada versi shell. Seluruh perintah shell (ls … red) menghasilkan iterator Python sehingga perintah tersebut dapat digunakan dengan loop for Python.

Akses Basis Data dengan Marcel Shell

Anda dapat mengintegrasikan akses database dengan saluran pipa marcel. Pertama, Anda perlu mengonfigurasi akses database di file konfigurasi, ~/.marcel.py, misalnya.

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

DB_DEFAULT = 'jao'

Ini mengonfigurasi akses ke database Postgres bernama acme, menggunakan driver psycopg2. Koneksi dari marcel akan dibuat menggunakan pengguna jao, dan profil database diberi nama jao. (DB_DEFAULT menetapkan profil basis data jao sebagai profil yang akan digunakan jika tidak ada profil yang ditentukan.) Setelah konfigurasi ini selesai, basis data sekarang dapat dikueri menggunakan operator sql, misalnya.

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

Perintah ini menanyakan tabel bernama part, dan membuang hasil kueri ke dalam file ~/reorder.csv, dalam format CSV.

Akses Jarak Jauh dengan Marcel Shell

Sama halnya dengan akses database, akses jarak jauh dapat dikonfigurasi di ~/.marcel.py. Misalnya, ini mengonfigurasi cluster 4-node:

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

Kluster dapat diidentifikasi sebagai lab dalam perintah marcel. Parameter pengguna dan identitas menentukan informasi login, dan parameter host menentukan alamat IP node di cluster.

Setelah cluster dikonfigurasi, semua node dapat dioperasikan sekaligus. Misalnya, untuk mendapatkan daftar pids proses dan baris perintah di seluruh cluster:

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

Ini mengembalikan aliran tupel (alamat IP, PID, baris perintah).

Untuk informasi lebih lanjut kunjungi:

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

Marcel cukup baru dan sedang dalam pengembangan aktif. Hubungi kami jika Anda ingin membantu.