Questo, da un post sul mio blog qualche mese fa, è passato dall'idea che pensavo fosse cool a uno dei migliori piccoli hack che ho tossito nella memoria recente. Lo cito per intero qui:
==================
Trascorro molto tempo a Bash. Per i non iniziati, bash è un sistema che troverai sulla maggior parte delle macchine unix e, per fortuna, alcune finestre e tutti i Mac là fuori. A prima vista, non è altro che un'interfaccia a riga di comando, e quindi fuori dal radar della maggior parte degli utenti che vedono cose come un anacronismo che preferiscono dimenticare.
Faccio quasi tutto in bash. Ho letto la mia e-mail da una riga di comando, motivo per cui evito e-mail contrassegnate. Navigo nelle directory, modifico i file, mi occupo del checkout e della consegna del mio codice sorgente quotidiano, cerco file, eseguo ricerche all'interno dei file, riavvio la macchina e occasionalmente sfoglio pagine Web dalla riga di comando. bash è il cuore e l'anima della mia esistenza digitale.
Il problema è che tendo ad aprire circa 6 finestre bash alla volta. Oggi al lavoro, ne avevo uno che eseguiva un web server, un altro che armeggiava con il mio database, un terzo, un quarto e un quinto che modificavano file diversi, mentre un sesto stava macinando via attraverso la mia macchina cercando di registrare i nomi di ogni file sul sistema. Perché? Perché è utile poter cercare in un tale archivio se si desidera sapere dove trovare un oggetto per nome file.
Quando lo fai, finisci con molte finestre nella barra di controllo chiamate semplicemente "bash". Questo va bene se ne hai solo uno, ma è un'agonia quando ne hai 6 o più .... e altre due dozzine di cose in corso. Ho tre monitor sotto il comando simultaneo di una coppia tastiera / mouse e sento ancora il bisogno di più. Ognuna di quelle finestre ha diversi terminali bash aperti.
Quindi l'ho messo insieme. Innanzitutto, posiziona queste righe nel tuo .bash_profile:
export PROMPT_COMMAND='export TRIM=`~/bin/trim.pl`'
export PS1="\[\e]0;\$TRIM\a\]\$TRIM> "
trap 'CMD=`history|~/bin/hist.pl`;echo -en "\e]0;$TRIM> $CMD\007"' DEBUG
Ho esaminato e scritto decine di paragrafi su come tutto questo funziona ed esattamente perché è impostato così com'è, ma non sei veramente interessato. Fidati di me. C'è un intero capitolo di un libro sul perché ho fatto "CMD = ...
; echo ..." su quella terza riga. Molte persone (incluso bluehost, dove è ospitato il mio altro dominio) stanno ancora usando e la vecchia versione di bash con importanti bug nel modo in cui gestisce le trappole, quindi ne siamo bloccati. Puoi rimuovere il CMD e sostituirlo con $ BASH_COMMAND se sei aggiornato sulla tua versione bash e hai voglia di fare ricerche.
Comunque, il primo script che uso è qui. Crea un bel prompt che contiene il nome e la directory del tuo computer, suddivisi per una lunghezza ragionevole:
============trim.pl===========
#!/usr/bin/perl
#It seems that my cygwin box doesn't have HOSTNAME available in the
#environment - at least not to scripts - so I'm getting it elsewhere.
open (IN, "/usr/bin/hostname|");
$hostname = <IN>;
close (IN);
$hostname =~ /^([A-Za-z0-9-]*)/;
$host_short = $1;
$preamble = "..." if (length($ENV{"PWD"})>37);
$ENV{"PWD"} =~ /(.{1,37}$)/;
$path_short = $1;
print "$host_short: $preamble$path_short";
==============================
C'è un avvertimento nella parte superiore di questo post sul blog che dovresti leggere ora prima di iniziare a fare domande stupide come "Perché non hai semplicemente usato la variabile d'ambiente HOSTNAME tramite @ENV?" Semplice: perché non funziona con tutti i sistemi su cui l'ho provato.
Ora per la parte davvero interessante. Ricorda la riga 3 dell'aggiunta .bash_profile?
trap 'CMD=`history|~/bin/hist.pl`;echo -en "\e]0;$TRIM> $CMD\007"' DEBUG
Sta scaricando l'output dello script trim.pl nello stesso contenitore di prima, stampando sia il prompt dei comandi che il titolo della finestra, ma questa volta sta aggiungendo il comando che hai appena digitato! Ecco perché non vuoi fare tutto questo nel tuo .bashrc: qualsiasi script che esegui (sulla mia macchina, man è uno di questi) attiverà questa cosa su ogni riga. la produzione dell'uomo viene seriamente confusa da ciò che stiamo facendo qui. Non stiamo esattamente giocando bene con il terminale.
Per afferrare il comando che hai appena digitato, prendiamo la storia di Bash e la tagliamo un po ':
===========hist.pl============
#!/usr/bin/perl
while (<STDIN>)
{
$line = $_
}
chomp $line;
$line =~ /^.{27}(.*)/;
print $1;
==============================
Quindi ora ho un bazillion di finestre in corso e dicono cose come:
castro: /home/ronb blog
Ron-D630: /C/ronb/rails/depot script/server
Ron-D630: /C/ronb/rails/depot mysql -u ron -p
Ron-D630: /C/ronb/rails/depot find . > /C/ronb/system.map
Ron-D630: /C/ronb/rails/depot vi app/views/cart.html.erb
Ron-D630: /C/perforce/depot/ p4 protect
Ron-D630: /C/perforce/depot/ p4 sync -f
Ron-D630: /C/perforce/depot/
Dalla piccola barra felice nella parte inferiore dello schermo, ora posso dire quale è quale a colpo d'occhio. E poiché abbiamo impostato PS1, non appena un comando termina l'esecuzione, il nome del comando viene nuovamente sostituito dall'output di trim.pl.
AGGIORNAMENTO (stesso giorno): questa roba (le voci .bash_profile) mi ha fatto venire l'inferno quando l'ho provato nel mio .bashrc. Il tuo .bashrc viene eseguito da script non interattivi ogni volta che invochi bash come lingua. L'ho colpito quando stavo cercando di usare l'uomo. Tutti i tipi di immondizia (il testo completo del mio .bashrc, oltre ai caratteri di escape) sono apparsi nella parte superiore della pagina man. Suggerirei di provare questa gemma con una rapida invocazione "man man" alla riga di comando una volta che avrai messo tutto insieme.
Immagino sia tempo per me di estrarre la spazzatura personalizzata dal mio .bashrc e metterlo dove appartiene ...
Per inciso, mi sono ritrovato a scrivere "trappola per uomo" ad un certo punto di questo processo.