Visualizzazione post con etichetta shell. Mostra tutti i post
Visualizzazione post con etichetta shell. Mostra tutti i post

2014-06-16

Verifica in bash se una variabile è numerica

Oggi una mia necessità era di verificare se una variabile era di tipo numerico ed il valore maggiore o uguale a zero.
Dopo qualche tentativo sono arrivato alla conclusione che il mio modo preferito di eseguire la verifica era:
A=X
B=5
[ $A -ge 0 ] 2>/dev/null && echo Numerico
[ $B -ge 0 ] 2>/dev/null && echo Numerico
l'aggiunta di "2>/dev/null" permette di non ottenere il messaggio di errore "-bash: [: A: integer expression expected"
Il numero deve essere positivo oppure zero, se si vogliono verificare anche i numeri negativi l'allungo un pochino:
[ $A -ge 0 -o $A -le 0 ] 2>/dev/null && echo Numerico
Per una prova più ampia:
for VAR in 0 1 2 3 4 5 50 100 1000 -1 -2 -5 -50 -100 -100 A C 2A 10X X1 X5
do
[ $VAR -ge 0 -o $VAR -le 0 ] 2>/dev/null && echo $VAR num || echo $VAR NON num
done
Il funzionamento si basa sul comando built-in [ della bash  che implementa il comando test di unix, restituisce un valore di ritorno vero/true solo se la condizione è valida e corretta, quindi confrontando numericamente con l'operatore -ge il valore della variabile rispetto allo zero per verificare se è maggiore o uguale si ottiene vero solo se il contenuto della variabile è un numero valido, altrimenti si ottiene falso. Se il contenuto della variabile non fosse un numero valido allora si otterrebbe il messaggio di errore che possiamo sopprimere con 2>/dev/null che lo redirige verso la device virtuale che distrugge tutto quello che riceve, come se fosse un buco nero.

2011-09-08

Bash e correzione di un lungo nome di file

Se con la shell bash capita di aver creato un file con il nome sbagliato si ricorre al comando mv
mv nome-lunghissimo-e-difficile-da-scrivere-corrotto nome-lunghissimo-e-difficile-da-scrivere-corretto
Non a caso ho scelto questi due nomi in cui la differenza consiste di una sola lettera in quanto gli errori di digitazione d solito sono brevi, la potenza della bash permette di utilizzare un metodo alternativo:
mv nome-lunghissimo-e-difficile-da-scrivere-corr{o,e}tto
In questo modo al comando mv vengono passati due nomi, il primo con la lettera o al posto del pezzo con le graffe, il secondo con la e. Non sempre puo' risultare comodo ma in alcun casi l'ho trovato impagabile... essendo poi open source... effettivamente lo e'.

2011-09-02

Clipboard e bash con xclip

Mi capita spesso di dover copiare da e verso la clipboard dalla shell ma non sempre risulta comodo ed utile farlo con Ctrl-INS oppure con il tasto centrale del mouse. A volte la necessità è quella di inserire in un file una parte del contenuto di un messaggio di posta elettronica. Per questo c'è xclip, il suo compito è quello di leggere ( richiamandolo senza opzioni ) oppure scrivere ( richiamandolo con l'opzione -o ) del contenuto della clipboard fornita da X.
Supponiamo di dover selezionare con grep le righe di un messaggio di posta elettronica che contengono un particolare indirizzo IP possiamo utilizzare, dopo aver copiato in clipboard le righe interessate:
xclip -o | grep 10.0.0.1
Se dovessimo invece spedire in chat l'output di un comando come la lista dettagliata dei file in una directory:
ls -l | xclip
e poi si può incollare nella finestra della chat il contenuto

2011-07-13

Bash script per effetto matrix, poi multicolore

Leggendo i cinguettii ho notato un post interessante sull'utilizzo di bash per la generazione di un rudimentale effetto Matrix, intendo quelle schermate in cui dei caratteri verdi scorrevano verso il basso...


tr -c "[:digit:]" " " < /dev/urandom | dd cbs=$COLUMNS conv=unblock | GREP_COLOR="1;32" grep --color "[^ ]"

provare per credere.

Guardandolo con il mio amico/collega Gianni per decifrarne il funzionamento e tratte le varie conclusioni ho raccolto la sua sfida: Adesso andrebbe modificato per far comparire i numeri pari di un colore ed i dispari di un altro colore
Nessun problema! dico io, aggiungo un grep dopo aver impartito il valore always all'opzione --color per colorare anche in caso di output in pipe:
tr -c "[:digit:]" " " < /dev/urandom | dd cbs=$COLUMNS conv=unblock | GREP_COLOR="1;31" grep --color=always "[02468]" | GREP_COLOR="1;32" grep --color=always "[13579]"
Ops... non funziona... ma perché?
Perché ho scelto di colorare di rosso i numeri pari e poi di verde i dispari, allora provo ad invertire, dispari rosso e pari verde:
tr -c "[:digit:]" " " < /dev/urandom | dd cbs=$COLUMNS conv=unblock | GREP_COLOR="1;31" grep --color=always "[13579]" | GREP_COLOR="1;32" grep --color=always "[02468]"
La trappola era la presenza delle cifre dispari nella sequenza di caratteri che colorano l'output, tale sequenza veniva di nuovo colorata dal secondo grep.

2011-07-11

Qualcuno ha cancellato e ricreato la directory corrente? Niente paura!

In Unix la cancellazione di un file aperto da qualche processo è permessa perché consiste sono nell'eliminazione del suo riferimento in una directory ma il file seguita ad esistere fino a quando qualche directory ha un suo riferimento oppure qualche processo lo mantiene aperto. Anche una directory può essere cancellata se qualche processo ce l'ha come directory corrente, se provate a creare una directory di prova /tmp/prova, vi ci spostate e provate a cancellarla vi viene permesso e tentando di leggere il contenuto della directory con ls non si ottiene nulla* Nella shell corrente il percorso corrente rimane impostato, anche se in una directory inesistente, ma se ricreiamo la directory il problema permane in quanto quello che è stato memorizzato è il file della directory corrente precedente che non esiste più. A questo punto si dovrebbe rieseguire il comando cd per riposizionarsi nella nuova directory. Tornare indietro di una non si può, il comando cd .. non può funzionare in quanto non esiste più il riferimento nella directory corrente, va rieseguito il comando cd con il percorso assoluto e se si tratta di un lungo percorso può essere noioso. In questa condizione possiamo eseguire ancora il comando pwd per reperire il percordo della directory corrente, la shell risponde in maniera corretta. Quindi una soluzione comoda è eseguire il comando cd $(pwd) che costringe il comando cd a ripercorrere tutto il percorso necessario da / per riposizionarsi ma non siamo costretti a digitare di nuovo tutto quanto.

* i comportamenti variano tra le diverse implementazioni e versioni di Unix.

2011-06-29

Sequenze di comandi con la shell

Da sempre la shell Unix ha permesso di impartire sequenze di comandi che avessero qualche correlazione tra di loro, le correlazioni sono molteplici e proverò con questo post a descriverle.
Il primo modo per impartire una serie di comandi è di digitare i comandi uno di seguito all'altro terminando ognuno con ENTER, con la shell interattiva il comando successivo viene eseguito al termine del comando precedente ma non prima di aver premuto il tasto ENTER che lo sottomette. Per evitare il tempo di attesa tra la fine del primo comando e la pressione del tasto ENTER per il successivo si può iniziare a digitare il comando anche prima della comparsa del prompt da parte della shell ma non sempre si riesce ad essere sufficientemente veloci; a tal proposito si possono digitare i comandi separati da punto e virgola ( ; ) e premere ENTER solo alla fine dell'ultimo. In questo modo i comandi verranno eseguiti uno di seguito all'altro senza attese. Esempio per consultare l'orario prima e dopo l'esecuzione di una copia di directory:
date ; cp -a src_dir dst_dir ; date
L'esecuzione dei comandi successivi può essere condizionata in base all'esito del precedente: separando con && due comandi si condiziona l'esecuzione del secondo in base all'esito del primo, se il primo si conclude positivamente allora viene eseguito anche il secondo. Ricordo che per esito positivo si intende che l'exit code del programma deve essere 0 ( zero ), l'exit code di un programma può essere verificato con la shell utilizzando la variabile predefinita $? . La sequenza di comandi può essere lunga a piacere. Esempio di comando condizionato dal precedente, se la compilazione si completa positivamente si può eseguire il programma:
cc -o prova prova.c && ./prova

Il condizionamento di esecuzione può essere anche invertito con || in modo tale da eseguire il secondo solo se il primo è fallito ( quindi exit code diverso da zero ). Esempio di comando alternativo eseguendo telnet se ssh fallisce, si sa che è preferibile ssh a telnet ma in sua assenza...:
ssh server || telnet ssh
I programmi possono essere eseguiti anche contemporaneamente separandoli con & che permette di eseguire il secondo appena iniziata l'esecuzione del primo, senza attenderne la fine. Esempio di esecuzione contemporanea di cancellazione di un file grande e la copia di un altro:
rm /tmp/grande_file & cp /tmp/altro_file /altrove/altro_file
Terminando con & l'ultimo ( o l'unico ) comando si ottiene di nuovo il prompt appena avviato il comando in modo da poter interagire subito di nuovo con la shell.
Un altro modo molto utilizzato per definire una sequenza di comandi è quello che redirige l'output ( che normalmente finirebbe sullo schermo ) come input ( normalmente la tastiera ) del comando seguente, per fare ciò si separano i due comandi con | ed i due programmi verranno eseguiti contemporaneamente con il sistema operativo che passa i dati in uscita dal primo nell'ingresso del secondo. Esempio di calcolo di occupazione di spazio su disco dei file o directory in ordine crescente di occupazione:
du -s * | sort -n

2011-06-23

Correzione comando precedente in bash

Nel post precedente Esecuzione del comando precedente con sudo in bash ho esposto un tipo di utilizzo della history delle shell con particolari riferimenti a bash, la tecnica esposta utilizza la scorciatoia !! che corrisponde al comando precedente.

Questa volta il comando precedente andrà modificato per essere eseguito con qualche correzione, il caso più frequente che mi si presenta è quello in cui devo verificare il contenuto di un tarball ( un archivio in formato tar di solito compresso con gzip o bzip2 ) e poi estrarne il contenuto.

2011-05-17

Sequenze di valori con bash

Negli script serve a volte una serie di numeri o caratteri in sequenza e bash prevede la funzionalità per generarli agevolmente.
Si utilizza quella che viene definita Brace Expansion e per ottenere una lista di numeri da 1 a 7 il formalismo previsto è {1..7} , i numeri 1 e 7, separati da una coppia di punti, rappresentano il numero iniziale e quello finale, quindi provando ad eseguire:
echo {1..7}
si ottiene
1 2 3 4 5 6 7
qualsiasi comando al posto di echo otterrà gli stessi valori come parametro quindi con il comando
touch file{1.20}.txt
otterremo venti file vuoti con i nomi "file1.txt", "file2.txt" e così via fino a file20.txt.

2011-05-07

Eseguire comandi esterni con vim l'editor

Quando si sta editando un file capita di dover eseguire qualche comando da shell, in questo vim viene in aiuto con alcuni comandi, se va aperta una shell per eseguire una serie di comandi si può digitare:
:sh<INVIO>
e viene presentato il prompt della nuova shell nella quale eseguire i comandi, per tornare a vim va fatta terminare la shell con exit oppure <Ctrl>D.

bc - calcolatrice a linea di comando per Unix / Linux

bc è un programma presente in Unix dal 1975 e sviluppato da due programmatori dei Bell Labs, nella versione iniziale bc era un front-end al programma dc, ovvero ne semplificava l'utilizzo mettendo a disposizione una sintassi simile al linguaggio C.
Il progetto GNU ne ha realizzato una versione che non si basa più su dc ed implementa nuove funzioni.
bc essendo un calcolatore permette anche di eseguire semplici somme, sottrazioni, moltiplicazioni e divisioni, sembra strano ricorrere alla linea di comando per eseguire dei calcoli quando ormai, tutte le distribuzioni mettono a disposizione calcolatrici con interfaccia grafica che possono soddisfare le esigenze di calcolo che si presentano quotidianamente. Personalmente sono rimasto fedele a bc da quando il mio accesso ai sistemi Unix era limitato ai terminali a carattere.
I calcoli semplici sono di immediata formulazione, riporto un esempio di utilizzo di bc con esempi di semplici calcoli ( in grassetto i comandi digitati ):
$ bc
3*6
18
45+30
75
.+10
85 
scale=2
22/7
3.14

quit
$
Si può notare che bc non presenta un prompt e quello che viene digitato viene interpretato al momento in cui si preme INVIO ed il risultato viene mostrato nella riga seguente. se la sintassi è sbagliata o si verifica un altro tipo di errore viene indicato con il relativo messaggio; per uscire viene mostrato nell'esempio il comando quit ma un semplice <Ctrl>D è sufficiente per chiudere bc.

2011-05-05

Esecuzione del comando precedente con sudo in bash

Se vi capita spesso di amministrare un sistema Unix/Linux e, come è giusto, non avete effettuato il login come root, potrebbe succedervi, come succede a me, di dimenticare di aggiungere sudo prima di un comando che necessita dei permessi di superuser, in questo caso l'operazione più noiosa sarebbe quella di scrivere un nuovo comando iniziando con sudo e poi riscrivere interamente il comando precedente, spero per voi che non facciate in questo modo, ci sono metodi un po' più veloci, se il comando da ripetere è breve potrebbe essere accettabile ma molti comandi sono lunghi, complessi e nascondo insidie da evitare.

2011-04-19

Ricerca di un comando precedente con bash - Il punto esclamativo (!)

Nel post Ricerca di un comando precedente con bash - Ctrl-R ho accennato, in un tuffo nel passato, a qualche utilizzo dei comandi per ricercare e ripetere comandi precedentemente digitati; ce ne sono tanti altri ed alcuni anche poco immediati e difficilmente memorizzabili. Ritengo che un comando per essere utilizzabile debba essere facile da ricordare, velocizzare notevolmente l'esecuzione dell'attività in corso e utilizzabile di frequente.
Come dicevo ci sono molti comandi ! o meglio il comando della shell è uno e si chiama history, con questo comando si possono ottenere gli ultimi comandi memorizzati dalla shell, davanti ad ogni comando viene riportato un numero che identifica univocamente il comando precedente.
Il carattere ! viene descritto nella sezione History Expansion della documentazione di bash in particolare ma anche di altre shell.

2011-04-08

Ricerca di un comando precedente con bash - Ctrl-R

Bash è una delle shell testuali più diffuse, fa parte del progetto GNU ed è l'evoluzione della Bourne shell, dal quale deriva il nome di cui "bash" è l'acronimo: "Bourne Again SHell".
Oggi per bash voglio affrontare l'argomento della ricerca di un vecchio comando se ci si ricorda almeno una parte di esso e non si vuole riscrivere tutto.
Esiste la combinazione -R che attende che si inizi a digitare qualche carattere e viene visualizzato l'ultimo comando che contiene la serie di caratteri digitati, quando il comando visualizzato è quello desiderato si può battere per rieseguirlo senza correzioni oppure battendo la freccia verso sinistra o verso destra si entra nella modalità di correzione che permette di modificare il comando prima di sottometterlo.

2011-01-18

Link in unix/linux - 4 - utilizzi

Nei post precedenti ho descritto i link nelle piattaforme unix-like poi ho distinto i link tra fisici e simbolici ed ho riportato le differenze tra i due tipi.
Ora passiamo a descrivere qualche utilizzo dei link.

2011-01-10

Link in unix/linux - 2 - i link fisici / hard link

Per analizzare la differenza tra i due tipi di link, che ricordo essere fisici o simbolici, riprendiamo l'output della prima serie di comandi del post precedente, i primi due file file1 e file2 oltre ad avere la stessa dimensione hanno anche il numero 2 nel secondo campo in cui il comando ls -l riporta solitamente il numero 1, difficilmente si nota questo campo e molti non ne conoscono nemmeno il significato.

2011-01-09

Link in unix/linux - 1


In Linux, unix e tutti i sistemi da essi derivati i link rivestono un ruolo molto importante, per questo è bene conoscerne le caratteristiche ed il comportamento.
Esistono due tipi di link, quelli fisici (o hard nella terminologia inglese) e quelli simbolici (o symbolic). I due tipi si differenziano principalmente nella natura e di conseguenza hanno comportamenti e vincoli diversi, il comando da eseguire per creare dei link dalla shell è ln, senza opzioni per i link fisici e con l'opzione -s per quelli simbolici; i parametri da fornire sono il file origine del collegamento ed il nuovo file che sarà collegato al primo, per esempio:
echo "contenuto del file originale" >file1
ln file1 file2
ln -s file1 file3
ls -l file*
ogni singolo comando viene eseguito senza generazione di output ad eccezione dell'ultimo che mostrerà l'effetto dei primi tre ovvero file1 che il comando echo tramite la direttiva di redirezione ha creato con la stringa fornita come parametro. file2 che ha la stessa identica dimensione di file1 e come vedremo in seguito lo stesso contenuto.
file3 di dimensione di soli 5 byte.

2010-12-24

Screen utility per condivisione shell


screen è un utility che ricordo aver usato circa 25 anni or sono.
Si tratta di un comando che permette di attivare numerose sessioni contemporanee sulla stessa console, si passa da una sessione (che viene sospesa) ad un'altra e si riottiene la schermata che si aveva al momento in cui è stata sospesa.
L'intera sessione di lavoro può essere sospesa e ripresa in seguito riottenendo tutte le sessioni aperte.