Editor di testo non interattivo: sed

Ad oggi non esiste sistema GNU/Linux che non sia dotato delle utility di elaborazione di testo: sed, awk. In specifico, in questo post si tratterà una panoramica generale su sed.

Cos’è:

Sed è un editor che si occupa della manipolazione di file di testo in modalità non interattiva. Come tutti gli editor di testo tale manipolazione opera attraverso la modifica e trasformazione di un file. La differenza però con gli editor comuni sta nel fatto che sed opera in standard non interattivo ed agisce in ordine: ricevendo un testo/file/stdin come input che poi sarà opportunamente trattato/modificato attraverso i parametri scelti con la specificazione delle righe, una alla volta; terminata questa fase si preoccuperà di inviare il risultato ad un file/stdout. Sostanzialmente più che un editor vero e proprio funge da filtro trasformatore.

NB: l’utilizzo di sed in tutte le sue varianti presuppone una discreta/media conoscenza delle regexp. A tal proposito è consigliata la lettura del post relativo; le espressioni regolari: regexp.

Sintassi del comando:

~$ sed --h

NB: sono elencate e commentate le opzioni generali di utilizzo. In specifico, le ritenute fondamentali.

-n, --quiet, --silent                  # evita che venga mostrato ciò che viene fatto "modalità silent" (uguale al parametro --quiet e/o -n)

-e script, --expression=script         # aggiunge lo script definito da riga di comando ai comandi da eseguire. Script definito all'interno degli apici '' e/o "" (più comandi sono separati dal punto e virgola ";")

-f script.sh, --file=script.sh         # aggiunge questa volta il contenuto del file script.sh ai comandi da eseguire.
-i[SUFFIX], --in-place[=SUFFIX]  # scriverà il risultato direttamente sul file originale modificandolo. 

NB: l'opzione -i può essere associata ad un suffisso che verrà preso in considerazione per creare un file backup come dagli esempi:
sed -i                  # modificherà il file originario senza creare alcun backup
sed --in-place          # identico all'esempio precedente -i
sed -i.backup           # modificherà il file originario creando salvando una copia di backup dello stesso
sed --in-place=.backup  # come l'esempio precedente  -i.backup

Comandi operatori:

NB: sed tende a suddividere i comandi generali secondo due categorie. La prima definisce quali e che tipo di operazioni eseguire. La seconda categoria invece racchiude le righe su cui operare e quindi delle specifiche delle stesse in termini di numero riga, classe, etc. Analizziamo in dettaglio:

p                      # "print" stampa la riga o il file
NB: Questa opzione è particolare. Per comprenderla analizzare gli esempi seguenti:
sed -e '' file     # stampa il file e non esegue nessuna operazione definita negli apici ''
sed -n -e '' file  # non esegue nessuna operazione e non stampa il file (opzione -n)
sed -e 'p' file    # stampa il file "operazione definita da p" (ogni riga trovata due volte)
sed -n -e 'p' file # come sopra ma questa volta associa l'operazione print alla modalità silent (stampa quindi una sola volta ogni riga)
d                      # "delete" elimina la riga

/regexp/p              # stampa solo le righe corrispondenti alla regexp espressa

/regexp/d              # elimina solo le righe corrispondenti alla regexp espressa
s/testo/sostituzione/  # sostituisce la stringa "testo" con "sostituzione" 

y/abcd/ABCD/           # come sopra ma analizza tutti i caratteri presi come riferimento nel modello1 "abcd" con i corrispondenti del modello2 "ABCD". Opera in sostituzione solo sui caratteri corrispondenti. Nell'esempio da abcd minuscolo a MAIUSCOLO.

g                      # definisce il parametro "global". Agisce su tutte le verifiche d'occorrenza di ogni riga trovata.Utile nelle sostituzioni recursive su più righe e/o per lasciare inalterate il resto delle righe (vedi più avanti nel post).

s/testo/sostituzione/g # sostituisce tutte le parole testo con sostituzione. Agisce su tutto il file e non si ferma solo alla prima riga trovata.

NB: l’ordine di suddivisione comandi vi risulterà inverso a quello descritto precedentemente. Ma vi rendererà il tutto di più facile comprensione.

Selettori di riga e specifiche operatori:

3                      # corrisponde alla terza riga

3p                     # stampa la terza riga di default due volte e il resto una sola volta (se associato ad opzione -n precedentemente descritta la stamperà una sola volta)

,                      # "virgola" corrisponde al range da prima a dopo il simbolo. Esempio: 1,3 (le righe da 1 a 3)

~                      # "infinito" è usato per definire ciò che c'è prima come partenza e ciò che c'è dopo come fine. Esempio: 1~3 (parte da riga 1 e poi ogni 3)

Esempi comandi,selettori di riga e specifiche operatori:

1,4d                    # le prime quattro righe sono eliminate

2,4d                    # le righe da 2 a 4 sono eliminate

5,10p                   # le righe da 5 a 10 sono stampate

1~2p                    # le righe dispari sono stampate (parte dalla prima riga e poi ogni due)

2~2p                    # le righe pari sono stampate (parte dalla seconda riga e poi ogni due)

4~3p                    # stampa le righe 4 7 10 13 ... etc (parte dalla quarta riga e poi ogni 3)

4~4d                    # elimina le righe 4 8 12 16 ... etc (parte dalla quarta riga e poi ogni 4)

/regexp/,/regexp-sost/p # stampa tutte le righe comprese tra la prima regexp espressa e la seconda.

2~2s/pippo/PIPPO/g      # sostituisce la parola pippo con PIPPO ma solo agendo sulle righe pari.Come da esempio la prima parte definisce le righe e la seconda l'operazione.

/^$/d                   # cancella tutte le righe vuote

/Pippo/p                # stampa tutte le righe in cui è presente Pippo (da usare con opzione -n)

/PIPPO/d                # cancella tutte le righe in cui è presente PIPPO e procede alla cancellazione del resto della riga in cui è presente la parola

s/PIPPO//g              # cancella la parola PIPPO in ogni riga sostituendola con nulla e lasciando il resto della riga intatto.

IMPORTANTE: questo esempio di doppio slash applicato alla frase seguente chiarisce il significato di una sostituzione applicata con nulla seguita dal simbolo g "global" che lascierà intatto il resto della riga.

NB: L’espressione di tipo s/PIPPO\,//g nella riga io adoro PIPPO, pluto e paperone opportunamente creata modificherà la frase in modo da risultare come io adoro pluto e paperone.

Prova su campo con sed:

~$ echo io adoro PIPPO, pluto e paperone >> prova.txt
~$ cat prova.txt
io adoro PIPPO, pluto e paperone

~$ sed -i -e 's/PIPPO\,//g' prova.txt
~$ cat prova.txt
io adoro pluto e paperone

NB: i più temerari ricorderanno leggendo il post precedente su regexp che spesso poteva capitare di dover usufruire dello slash / come simbolo da ricercare che quindi era considerato come un carattere speciale (come lo possono essere il punto,la virgola,etc) e che quindi per arrivare allo scopo era necessario utilizzare lo slash rovesciato “\” seguito dal carattere speciale da ricercare. Ovviamente in molte regexp di tipo sostitutivo ’s// ‘ potrebbe risultare fastidioso quindi scrivere continuamente \/ per effettuare una sostituzione come lo era l’esempio:

s/Linux/GNU\/Linux/g    # lo slash rovesciato \ tratta il seguente slash normale / come un carattere speciale. Altrimenti sarebbe considerato come fine regexp.Sostituzione della parola Linux con GNU/Linux in ogni riga.

Per evitare questa cosa si può scegliere di sostituire gli slash con altri limitatori come ad esempio i due punti “ : “come da esempio seguente.

s:regexp:sostituzione:g
In specifico per provare creaiamo un file prova.txt come da esempio:

~$ echo Linux >> prova.txt

~$ cat prova.txt
Linux

~$ sed -i -e 's:Linux:GNU/Linux:g' prova.txt

~$ cat prova.txt
GNU/Linux

Considerazioni: come sempre è utile capire che la potenza è nascosta nelle cose apparentemente banali. Bisogna tener conto che l’utilizzo di sed è fondamentale per la creazione di una pipe e che molto spesso è associato ad altre utility del suo genere per operazioni complesse all’interno di scripts. Il miglior modo per imparare quindi è come al solito: cominciare e provare, provare, provare. Saluti.

NB: questo post è una sorta di sommario e di appunti e quindi i riferimenti e la linea generale di trattamento del post, come nel precedente su regexp, sono legati al link ufficiale di riferimento su Advanced Bash-Scripting Guide.

# End

Le espressioni regolari: regexp.

Le espressioni regolari regexp sono alla base di tutto ciò che comprende la modifica, ricerca e sostituzione di una sequenza/stringa di caratteri;  risultano essenziali per l’utilizzo di applicazioni ed utilities da sempre sovrane nei sistemi UNIX e derivati come grep,sed,awk, oltre che essere alla base della programmazione e della conoscenza di bash. Nascono appunto per definire stringhe di caratteri e di metacaratteri. Per stringhe di caratteri si intendono caratteri semplici (numeri,lettere minuscole/maiuscole,accentate) e simboli ( .;*^[]{}/\ etc..) .

Le regexp sono spesso utilizzate in vari linguaggi di programmazione (bash,perl,etc..) anche se a volte possono essere scritte e interpretate in maniera differente da un linguaggio all’altro in linea generale  il concetto di base legato alle regexp resta lo stesso. Come già detto in precedenza se ne fà largo uso in molti applicativi, tra cui sed.

Sed è un manipolatore di testo più che conosciuto da tutti gli utenti GNU/Linux che agendo su un file ricerca e all’occorrenza sostituisce stringhe e/o classi di caratteri e simboli definiti. Tali stringhe sono opportunamente suddivise per funzione. La regex singola legata all’utilizzo di sed si identifica perchè posta all’interno di due slash ( / ) come da esempio:

/regexp/

NB: se i caratteri contenuti negli slash risultano essere testo semplice, sarà ricercata esattamente quella sequenza di caratteri avente distinzione “case sensitive” (per caratteri minuscoli e MAIUSCOLI). Spesso però al testo semplice si aggiungono determinati simboli che definiscono meglio e più specificatamente la regex da ricercare.

NB: non necessariamene una regex deve essere definita negli slash. Infatti solitamente anche comandi comuni quale ad esempio potrebbe essere un semplice grep potrebbero richiedere l’utilizzo di una particolare classe di caratteri facente parte delle regexp (il cui significato vedremo in seguito). Esempio:

~$ grep [[:digit:]] file.test
abc=123

Per prima cosa, come già detto precedentemente è bene elencare i simboli utilizzati nelle regexp e il loro significato.

SIMBOLI:

*   "asterisco" - accetta zero o più ripetizioni del carattere che lo precede.
  "punto" - qualunque carattere.

^   "apice" - messo all'inizio di una regex impone che la stringa cominci con quello che segue l'apice. Se usato con le parentesi quadre e prima di un carattere assume significato di negazione (tranne ciò che segue).

$   "dollaro" - se inserito alla fine della regex impone che la stringa finisca con ciò che precede il dollaro.

+   "più" - accetta una singola o più ripetizioni del carattere che lo precede.

[ ] "parentesi quadre" - tutti i caratteri all'interno delle parentesi sono presi in considerazione.

[^ ] "parentesi e apice interno" - tutti i caratteri interni le parentesi sono esclusi.

NB: il simbolo / “slash” come già detto apre e chiude l’espressione. Il simbolo \ “slash rovesciato” serve invece per trattare uno dei caratteri speciali che lo segue come un normale carattere. Esempio: \$ ricerca il simbolo del dollaro nel nostro file o nella nostra stringa.

Esempi di Set di caratteri semplici definiti dalle parentesi quadre:

[abc]     -  cerca i caratteri a b c nella stringa.

[a-k]     -  si riferisce a tutti i caratteri compresi nel range tra la lettera a e la k.

[C-In-o]  -  come prima con distinzioni "case sensitive". Cerca caratteri di range C e I ed n e o.

[0-9]     -  tutti i numeri.

[a-z]     -  tutti le lettere minuscole.

[A-Z]     -  tutte le lettere MAIUSCOLE.

[a-z0-9]  -  tutte le lettere minuscole e i numeri.

Esempi di negazione e combinazioni di parentesi quadre:

[^A-D]    -  corrisponde a tutti i caratteri tranne quelli contenuti nel range da A a D.

[Pp][Il][Pp][Oo] - corrisponde a tutte le combinazioni maiuscole e minuscole: PIPO,pipo,Pipo,pIpo,PIpo,piPo,PIPo,pipO,piPo..etc.

Classi di caratteri:

Oltre ai simboli e i set di caratteri semplici (lettere,numeri) ci sono classi di caratteri definite che in determinati casi possono risultare estremamente utili:

[:alnum:]  -  corrisponde a tutti i numeri e le lettere (sia minuscole che MAIUSCOLE comprese quelle accentate).Equivalente di [A-Za-z0-9].

[:alpha:]  -  corrisponde a tutte le lettere comprese quelle accentate (sia minuscole che MAIUSCOLE). Equivalente di [A-Za-z].

[:digit:]  -  corrisponde a tutti i numeri. Equivalente di [0-9].

[:lower:]  -  corrisponde a tutte le lettere minuscole. Equivalente di [a-z].

[:upper:]  -  corrisponde a tutte le lettere MAIUSCOLE. Equivalente di [A-Z].

[:blank:]  -  corrisponde a tutti gli spazi o tab.

[:space:]  -  corrisponde agli spazi.

[:cntrl:]  -  corrisponde ai caratteri di controllo.

[:print:]  -  corrisponde ai caratteri di range ASCII 32 - 126 compresi gli spazi.

[:graph:]  -  come [:print:] corrisponde ai caratteri di range ASCII 33 - 126 ma esclude gli spazi.

[:punct:]  -  corrisponde a tutti i caratteri di punteggiatura.

[:xdigit:] -  corrisponde a tutti i caratteri che possono formare un numero esadecimale. Equivalente di [0-9A-Fa-f].

NB: Allo stesso modo dei set di caratteri semplici, anche in questo caso  le classi di carattere vanno specificate e racchiuse in altre parentesi quadre []. Di conseguenza una classe esempio [:alnum:] và definita come:

[[:alnum:]]

Esempi di utilizzo di regexp all’interno delle specifiche di sed:

NB: chiarite le specifiche per simbologia e classi è bene fare qualche esempio di espressione mirata all’utilizzo di sed come da inizio post.

Esempi caratteri e simboli:


/./              - corrisponde a qualunque stringa contenente almeno un carattere.

/^#/             - qualunque stringa comincia con il carattere # (solitamente usato per definire un commento).

/ *$/            - qualunque stringa che finisce (definito con $) con uno o più spazi (spazi ripetuti definiti da *).

/[fui]/          - qualunque stringa che contiene anche solo una delle lettere f u ed i minuscole.

/^[fui]/         - qualunque stringa che comincia con uno dei caratteri f u ed i minuscoli.

/[^f]/           - qualunque stringa che non contiene la lettera f minuscola.

/^linux$/        - qualunque stringa che comincia con la parola linux e finisce con la stessa. Se ci sono stringhe contenenti altre parole e/o caratteri (prima e dopo) non saranno prese in considerazione.

/^[Ll]inux/      - qualunque stringa comincia con la parola linux con iniziale sia MAIUSCOLA che minuscola.

/^[Ll]inux+$/    - come l'esempio precedente ma comprende una o più ripetizioni della lettera x. Esempio: Linuxx , linuxxx, linuxxxxxx.

Esempi con set di caratteri:

/^[A-Z]+$/       - qualunque stringa composta da lettere MAIUSCOLE con almeno 1 carattere (lettere accentate escluse).

/^[a-z]+$/       - come il precedente esempio ma con lettere minuscole.

/^[0-9]+$/       - ancora uguale al precedente con i numeri.

Esempi con caratteri speciali \ (slash rovesciato):

/^[0-9]\{8\}$/    - qualunque riga che comincia con dei numeri ripetuti per 8 volte e che finisce con essi definito dal simbolo $ (esempio si date espresse in sequenza 16012010).

/^l\{5\}$/        - qualunque stringa contenente solo la lettera l minuscola ripetuta 5 volte e nient'altro (lllll).

/x\{10\}/         - qualunque stringa contenente la lettera x ripetuta almeno 10 volte (linux Linuxxxxxxxxxxxxx pippo).

/x\{2\}$/         - qualsiesi stringa contenente la lettera x ripetuta almeno due volte e nient'altro dopo di essa (linux Linuxxx).

Fatta una panoramica generale con qualche esempio utile, passiamo all’utilizzo base di queste espressioni. Prendiamo un file di testo semplice con delle stringhe esempio fatte da noi ed esercitiamoci attraverso l’uso di sed. Quindi:

~$ echo 12456 > prova.txt
~$ echo lettere_miste: f g h l o ; punteggiatura .:;, tab: 000000 >> prova.txt
~$ echo linuxxxxx : questo è un esempio >> prova.txt
~$ echo accentate: è ò à >> prova.txt
~$ echo Linux >> prova.txt

Salvato il nostro file, con stringhe esempio, non resta che provare a ricercare quelle interessate con la regexp giusta seguendo la sintassi di sed:

~$ sed -n -e '/regexp_da_inserire_qui/p' prova.txt

NB: Con il parametro finale p dopo gli slash / sed si limiterà a stampare ad output il risultato della ricerca delle stringhe corrispondenti la regexp scritta da voi nel file esempio.

Allo stesso modo si possono operare sostituzioni di parti di testo:

~$ sed -e 's/regexp/testo_da_sostituire_alla_regexp/g' prova.txt

In specifico, prendendo in esempio il file prova.txt creato precedentemente:

~$ sed -i.backup -e 's/^[Ll]inux/GNU\/Linux/g' prova.txt

NOTA:  bisogna fare un distinguo tra la fase di ricerca e quella di sostituzione. Se operiamo su una regexp per una semplice ricerca, sed si limiterà a stampare a schermo tutte le stringhe che iniziano o contengono la regexp da noi imposta. Esempio: ‘/^Linux/p’ .Al contrario se operiamo su una sostituzione del tipo:

's/^[Ll]inux/GNU\/Linux/' 

Sed sostituirà la parola Linux (iniziale sia MAIUSCOLA che minuscola) con GNU/Linux solo a patto che sia la prima parola della stringa.

NB: Come si nota dall’esempio lo slash rovesciato \ farà in modo di trattare lo slash successivo / come un normale carattere e non come la fine della regexp. In più operando su tale file e modificandolo creerà una copia di backup prova.txt.backup con le vecchies tringhe non sostituite.

NB: questo post non entra nelle specifiche del comando sed ma si limita ad una panoramica generalizzata di ciò che sed utilizza (regexp) per effettuare manipolazioni e sostituzioni di flussi di testo, così come avviene per awk,grep,ls o per gli script bash da noi generati. Tali specifiche saranno spiegate in post successivi riguardo le singole utilities.

Considerazioni Personali: talvolta ci sono più modi per arrivare allo scopo. Il miglior modo per imparare è sperimentare. Il post, non è altro che una sorta di annuario di ciò che è stato ampiamente descritto da link ufficiali di riferimento (advanced bash scripting) comprensivi di  qualche esempio personale mirato. Divertitevi, visto che il mondo delle regexp è molto più ampio di ciò che ci si aspetta (come direbbe un caro amico: questo argomento è una vera materia!). Alla prossima.

# End

Conversione tema Bootsplash in Fbsplash: bootsplash2fbsplash

Non troppo tempo fà sono stati publicati su questo blog gli articoli relativi ad alcuni temi per Bootsplash ed un nuovo tema dedicato per Arch Linux (questa volta per fbsplash). Ultimamente un utente della comunità di kde-look mi ha fatto notare (come già sapevo) che i temi publicati da me per Bootsplash non sono compatibili con fbsplash e/o gensplash, di conseguenza non si possono utilizzare con tale splash grafico, chiedendomi di riconfigurare tutto il path relativo i config e i percorsi delle immagini (per chi volesse seguire la discussione originale mediante commenti). In realtà però questa cosa non è necessaria. Difatti l’installazione di fbsplash prevede l’automatica installazione di un utility creata appositamente per convertire un tema creato per la vecchia patch Bootsplash in un tema per il più moderno fbsplash: bootsplash2fbsplash.

NB: siccome la discussione è nata con un tema specifico “tattoo’s girl”, vediamo di seguito come convertirlo da bootsplash a Fbsplash con pochi e semplici passaggi.

Per prima cosa scarichiamo il tema per Bootsplash e lo scompattiamo in una directory temporanea, come da esempio anche la home utente va bene:

~$ wget girltattoo
~$ tar jxvf 61403-girltattoo.tar.bz2

A questo punto creeremo il path “percorso” nel sistema che si riferiva al vecchio utilizzo di Bootsplash come se lo stessimo utilizzando come da esempio:

~$ su -
Passowrd:

~# mkdir /etc/bootsplash

NB: chiaramente discorso identico per chi preferisce l’utilizzo di sudo.

A questo punto copiamo il nostro tema nella directory creata che risultava essere quella di riferimento per la vecchia patch Bootsplash:

~# cp -r girltattoo/ /etc/bootsplash/

NB: come descritto nel post relativo per Bootsplash su Slackware in realtà la directory di riferimento dei temi risultava essere /etc/bootsplash/themes/ per comodità. L’utility bootsplash2fbsplash di conversione di cui si parla però utilizza un percorso preimpostato che linka verso /etc/bootsplash. Motivo per cui molti temi necessitano di un ulteriore semplice modifica anche nel config. Quindi come da esempio:

~# vi /etc/bootsplash/girltattoo/config/girltattoo.cfg

sarà modificata la sezione:

# name of the picture file (full path recommended)
jpeg=/etc/bootsplash/themes/girltattoo/images/verbose.jpg
silentjpeg=/etc/bootsplash/themes/girltattoo/images/silent.jpg

che diventerà come da esempio:

# name of the picture file (full path recommended)
jpeg=/etc/bootsplash/girltattoo/images/verbose.jpg
silentjpeg=/etc/bootsplash/girltattoo/images/silent.jpg

NB: Salvati i cambiamenti con il nostro editor preferito, dovremo ancora una volta modificare il nome del file di config. Questa operazione, è necessaria visto che come accadeva precedentemente, l’utility bootsplash2fbsplash per riconoscere i file config di tema ricerca un nome default che è (bootsplash) seguito dalla risoluzione prescelta, nel nostro caso (-1024×768); quindi come da esempio rinominiamo il file config del tema:

~# mv /etc/bootsplash/girltattoo/config/girltattoo.cfg /etc/bootsplash/girltattoo/config/bootsplash-1024x768.cfg

A questo punto non resta che lanciare l’utility che convertirà il tema, dopo aver avuto le accortenze prescritte fino ad ora:

~# bootsplash2fbsplash girltattoo 
o Parsed bootsplash-1024x768.cfg (1024x768)

NOTA GENERALE: la conversione di un tema da Bootsplash a Fbsplash non comporta cambiamenti di nessun tipo sulle immagini di base utilizzate dal tema. In specifico, il nome comprensivo di risoluzione è necessario all’utility per riconoscere il tema e non per effettuare cambiamenti di risoluzione sullo stesso.

NB: l’output ci notifica che è stato convertito il tema avente tale risoluzione. E’ l’utility stessa che si preoccuperà di trasferire il tema convertito nella directory di riferimento di fbsplash. Per verificare infatti:

~# ls -al /etc/splash/girltattoo/
-rw-r--r-- 1 root root 1210 14 gen 20:06 1024x768.cfg
drwxr-xr-x 2 root root 4096 14 gen 18:57 images

NB: da notare che non solo sono state create directory e file ma sono cambiati anche i path degli stessi per essere utilizzati da fbsplash. Un banale cat infatti ci farà capire meglio:

~# cat /etc/splash/girltattoo/1024x768.cfg

...
# name of the picture file (full path recommended)
pic=/etc/splash/girltattoo/images/verbose-1024x768.jpg
silentpic=/etc/splash/girltattoo/images/silent-1024x768.jpg
...

A questo punto non resta che utilizzare fbsplash in modo standard ricreando l’immagine init del kernel con l’immagine splash scelta. Esempio su Arch (parte relativa agli HOOKS e mkinitcpio). Stesso discorso teorico riguardo ad un immagine init per altre distribuzioni). Ovviamente al termine di queste operazioni bisogna aggiornare il boot manager (Lilo e/o GRUB).

#  End

Scripts e menu dinamici in PekWM: pipemenus.

Un pò di tempo fà, nel post che trattava la configurazione generale di OpenBox si è accennato all’utilizzo di script (bash,perl,python…etc) che potessero essere implementati nel menu desktop “statico” del wm. Anche in PekWM questa funzione è supportata attraverso ciò che in gergo tecnico viene definito pipemenu. I pipemenus infatti sono menu “dinamici” (contenenti categorie,sottocategorie,link,funzioni,etc) che fanno capo al richiamo di semplici e/o complessi scripts.

Un esempio generico che sembra essere molto richiesto, può essere quello della visualizzazione della data e dell’ora nel menu di PekWM.

NB: per prima cosa ci procuriamo e/o scriviamo con il nostro editor preferito lo script necessario. Nel nostro esempio pkw-dateclock.sh (bash).

 ~$ vi pkw-dateclock.sh
#!/bin/bash
# pkw-dateclock.sh
date=$(date +%A\ %d\ %b\ \%H\:%M)
echo "Dynamic {"
echo " Entry = \"$date\"    { Actions = \"Exec xclock & \" }"
echo "}"
exit

NB: lo script stampa ad output di menu dinamico ciò che ci interessa (data e ora) ed apre l’utility xclock al click singolo del mouse.

Salvato lo script, è buona norma mantenere ordine e quindi spostiamo lo script creato in una sottodirectory /scripts creata nella directory di riferimento del wm (nel nostro caso PekWM la directory di riferimento resta ~/.pekwm/ ) . Ovviamente essendo uno script eseguibile provvederemo a dargli i permessi di esecuzione. Esempio:

~$ mkdir ~/.pekwm/scripts
~$ cp pkw-dateclock.sh ~/.pekwm/scripts/
~$ su -
~# chmod +x ~/.pekwm/scripts/pkw-dateclock.sh

Finito il lato script, non resta che richiamare tale funzione modificando il menu statico di PekWM ed aggiungendo l’Entry necessaria come da esempio:

~$ vi ~/.pekwm/menu
Submenu = "Data/ora" { Icon = "dateclock.png" ;
        Entry = "" { Actions = "Dynamic  /home/utente/.pekwm/scripts/pwk-dateclock.sh"}
 }

NB: la modifica del menu statico di PekWM segue i soliti parametri. Se ci fossero dubbi in merito consultare il post: Un altro cugino della famiglia *box: PekWM – sezione MENU.

Il risultato finale sarà come da screen:

Allo stesso modo, si possono eseguire scripts in perl che richiamino statistiche di sistema, come il consumo della memoria RAM, percentuali, come da esempio:

~$ vi ~/.pekwm/scripts/stat.pl
#!/usr/bin/perl

print "Dynamic {\n";
($parta,$partb) = split(/Mem:/,`free -m`);
($partc,$partd) = split(/^           /,$partb);
($partf,$partg) = split(/        /,$partd);
$partg =~ s/ //g;
print "Submenu = \"Memory\" {\n";
 print "Entry = \"$partg/$partf mb\" { Actions = \"Exec \" }\n";
print "}\n";    

($pa,$pb) = split(/COMMAND\n/,`ps -e -o pcpu,cpu,nice,state,cputime,args --sort pcpu | sed '/^ 0.0 /d'`);
(@array) = split(/\n/,$pb);

print "Submenu = \"CPU Usage\" {\n";

foreach $temp (@array) {
 $temp =~ s/^ //;
 ($percent,$process) = split(/ .{19}/,$temp);
 if ($process =~ /\//) {
 ($pops,$use) = split(/\/(?!.*\/)/,$process);
 } else {
 $use = $process;
 }    
 print "Entry = \"$use:  $percent" . "%\" { Actions = \"Exec \" }\n";

}

print "}\n";    
print "}\n";

Modifichiamo il menu statico di PekWM aggiungendo anche in questo caso la solita Entry relativa:

SubMenu = "Stat" { Icon = "boxstats.png" ;
        Entry = "" { Actions = "Dynamic /home/user/.pekwm/scripts/stat.pl" }
 }

Il risultato sarà:

# End