zsh: The Powerful Shell

La shell è l’interfaccia per eccellenza degli smanettoni.

Quando si comincia a farne un utilizzo costante, si sente il bisogno di spingersi oltre, scoprendo/creando delle funzionalità che ci semplificano ulteriormente la vita.

Almeno questa è stata la mia reazione… un bel po’ di tempo fa.

Dopo aver provato a personalizzare la bash, mi resi conto che le mancavano molte funzionalità presenti in altre shell. Decisi di cambiare proprio tipo di shell ed iniziai ad utilizzare la tcsh, una versione migliorata di csh.

Ero abbastanza soddisfatto della mia configurazione, quando un amico mi parlò di zsh.

funzionalità

Questa potente shell, come moltissimi progetti informatici (vedi ruby), prende il meglio delle caratteristiche da altri progetti simili e aggiunge, tramite un ottimo collante, altre funzionalità originali.

Si può considerare questa shell come una sorta di superset di sh, ash, bash, csh, ksh, e tcsh.

Qualche anno fa avevo pure fatto un piccolo screencast che illustrava alcune caratteristiche di zsh…

Andiamo a vedere nel dettaglio alcune delle funzionalità più importanti.

Command line completition

In zsh il completamento non si limita ai nomi dei programmi, ma include anche i vari argomenti ed i parametri degli stessi.

Costruendoli anche dinamicamente.

Il tutto completamente personalizzabile.

Tra le altre cose, questa funzionalità integra un sistema di caching, per i completamenti più dispendiosi (es: il completamento di tutti i nomi dei programmi disponibili nei repository debian)

Un’altra interessante caratteristica del sistema di completamento è il correttore ortografico.

File globbing

Il potentissimo file globbing di zsh permette di specificare una determinata categoria di file, facendo a meno di utilizzare programmi esterni come find/args.

Vediamolo in azione:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# tutti i file nella directory /tmp e nelle relative sottodirectory, di proprietà dell'utente kalos
ls -l /tmp/**/*(u:kalos:)

# tutti i file regolari (non symlink, dir, ecc)
ls -l /boot/*(.)

# tutti i file regolari ed eseguibili
ls -l /bin/*(.x)

# tutti i file che non hanno abilitata la scrittura per il gruppo di appartenenza
ls -l /tmp/**/*(.:g-w:)

# tutti i file piu' vecchi di 20 minuti
ls -l /tmp/.(mm+20)

# tutti i file vuoti
ls -l /tmp/*(.L0)

# tutti i file (comprese le directory) senza estenzione
ls -ld ^?*.*(D)

Gestione avanzata di variabili e array

  • Sostituzione delle variabili
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FILE="/home/kalos/doc/ruby/rspec.pdf"

# stampa il contenuto della variabile $FILE sostituendo le occorrenze di "kalos" con "marco"
echo ${FILE//kalos/marco}
» /home/marco/doc/ruby/rspec.pdf

# stampa solo il nome del file (come il programma "basename")
echo ${FILE##*/}
» rspec.pdf

# stampa solo il percorso del file (come "dirname")
echo ${FILE%/*.*}
» /home/kalos/doc/ruby

# elimina l'estensione nella stringa salvata nella variabile
FILE="rspec.pdf"
echo $FILE:r
» rspec

# per ulteriori informazioni
man 1 zshexpn
  • Array ed array associativi

Questa funzionalità è molto utile se si stanno creando degli script non proprio banali.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
array=(foo bar lillo boom)

# stampa l'ultimo elemento
echo $array[-1]
» boom

# stampa dal secondo al penultimo elemento
echo $array[2,-2]
» bar lillo

# dichiarazione di un array associativo
typeset -A array_ass

# inizializzazione dell'array
array_ass=(uno 1 due 2 tre 3 quattro 4)

# stampa solo le chiavi
print ${(k)array_ass}
» uno due tre quattro

# stampa i valori
print ${(v)array_ass}
» 1 2 3 4

# ordina le chiavi in base ai nomi
print ${(ok)array_ass}
» due quattro tre uno

# modifica il valore di un array associativo
array_ass[tre]='03'

# stampa l'array ordinato
print ${(o)array_ass}
» 03 1 2 4

Alias

Zsh amplia il concetto di aliasing introducendo:

  • alias globale

È un tipo di alias che può essere utilizzare in qualsiasi parte della riga di comando e non solo all’inizio.

1
2
3
4
5
6
7
8
9
# definizione degli alias
alias -g Il="| less"
alias -g N="&>/dev/null"

# manda in pipe il file letto con cat a less
cat /var/log/messages Il

# redirige lo standard output e lo standard error nel nulla
rm -rf /tmp N
  • alias dei suffissi

Se si esegue un file con un certo suffisso, viene automaticamente eseguito il programma associato

1
2
3
4
5
alias -s txt=$EDITOR
alias -s {mpg,mpeg,avi,ogm,wmv,m4v,mp4,mov,mkv}="mplayer"

# come un nerd guarda un film ;)
~FILM/totoro.avi

Modalità compatibilità

Zsh ha la possibilità di emulare il comportamento delle shell csh, sh e ksh (la sua parente più vicina).

Questo ci permette, ad esempio, di utilizzare la nostra shell come shell predefinita di sistema per tutti gli script di init, ecc.

Le modalità di compatibilità possono essere eseguite in due modi:

  • creando un link della shell da emulare che punta al binario di zsh (ln -s /bin/zsh /bin/csh). In questo caso si ottiene un’emulazione completa della shell.

  • abilitando selettivamente tutte le funzionalità da emulare, ad esempio con “setopt KSH_GLOB”

History condiviso da più sessioni contemporaneamente

Questa funzionalità può tornare utile, ad esempio, quando più persone stanno lavorando sullo stesso sistema e vogliono condividere i comandi lanciati

configurazione

La configurazione di zsh non è tra le più semplici.

Per facilitare le cose, è stato realizzato un bel progetto collaborativo.

oh-my-zsh

E’ un piccolo framework che fornisce una configurazione abbastanza completa ed un sistema di plugin aggiuntivi.

installazione

1
wget --no-check-certificate https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh

utilizzo

Per utilizzarlo basta modificare il file ~/.zshrc per abilitare qualche plugin e configurare il tema del prompt preferito.

aggiornamento

Una delle funzionalità più importanti di questo framework è il costante aggiornamento effettuato dalla vasta comunità che ci lavora.

Di default il programma chiede di auto-aggiornarsi ogni settimana, attraverso il file oh-my-zsh/tools/upgrade.sh, che non fa altro che eseguire il comando “git pull origin master”.

il mio repository di oh-my-zsh

Viste le potenzialità di questo framework, da qualche tempo ho deciso di adottarlo, aggiungendogli tutte le mie personalizzazioni che ho collezionato nel corso degli anni.

Ho semplicemente fatto un fork del progetto, modificato qualche file ed aggiunto le mie configurazioni sotto la directory custom/

Se si vuole utilizzare/provare le mie personalizzazioni è sufficiente installare il mio fork di OMZ

1
wget --no-check-certificate https://github.com/kalos/oh-my-zsh/raw/master/tools/install.sh -O - | sh

come gestire un proprio fork di OMZ

Se si vuole gestire la propria configurazione di zsh attraverso OMZ, questi sono i semplici passi da compiere:

  • fare il fork del progetto su github
  • aggiungere al repository git l’url del repository ufficiale di OMZ
1
git remote add upstream git://github.com/robbyrussell/oh-my-zsh.git
  • modificare il file tools/install.sh sostituendo git pull origin master con

git fetch upstream && git merge upstream/master

risorse utili

zshwiki

zsh-lovers da grml

oh-my-zsh

il mio repository oh-my-zsh

zsh dotfiles di strcat

Altri rifetimenti in merito li potete trovare nei miei bookmark salvati su delicious

Comments