Newsgroup: it.comp.os.linux.iniziare
Titolo: bash (sh) variabile e comandi ansi

Tempo fa, avevo fatto uno script (script1) che faceva controlli su degli
indirizzi IP e che si appoggiava all'output di un'altro script (script2) per
avere gli IP.
Col tempo ho modificato l'output di questo secondo script (script2) aggiungendo
i colori ansi.
 
Lo script (script1) é (semplificato):
 
for IP in $(script2)
do
    d=$(COMANDO $IP)
...
...
done
 
 
COMANDO mi fallisce, in quanto, invece di trovarsi un valore di IP (127.0.0.5),
si trova un ".[0m127.0.0.5" ossia il comando ansi per il colore (.[0m).
Se faccio un banale echo "$IP" vedo solo il valore nunerico, in quanto in
questo caso, il comando ansi ripristina i colori base.
Con un pipe allo split di awk:
        echo "$IP" | awk'{split($0, k, "m") ; print k[2]}'
apparentemente risolvo, ma non mi sembra una soluzione ideale.
Esiste qualche alternativa piú "pulita"?
Ossia mettere in una variabile solo la parte stampabile senza gli eventuali
comandi ansi?
 
-- 
94% dei calcolatori hanno lime corrotte, inutilizzate e possibilmente nocive.
   * Prestazioni del PC di spinta
   * Aumenti la stabilita' del sistema
   * Eviti .exe errori.
+-----#13--------------------------Campagna contro gli spam idioti.---------+


 
un modo puo essere una opzione a script1 che dica di non emettere in 
output i comandi ansi
 
un altro modo verificare che stdout sia connesso ad un terminale e se lo 
è emettere i comandi ansi altrimenti no
 
 

 un altro modo verificare che stdout sia connesso ad un terminale 
Ossia?
 
-- 
+---------------------------------------------------------------------------+
|    ero li assorto nei miei pensieri e uno mi ha chiesto l'ora... ho       |
|    dovuto sparargli una fucilata... stavo meditando... e che cazzo!       |
+-----#14--------------------Campagna contro le pubblicita` idiote.---------+


 
 
Non so se in awk si possa fare
in perl esiste un comando -t <stream>, in  python stdout.isatty()
funzioni che ritornano vero se stdout è connesso ad un terminale
 
 
 

> output i comandi ansi
 
Dire a script1 di non mettere comandi ansi, mi sembrava eccessivamente
complicato, a me interessava che fosse script2 a filtrare i comandi...
 
Ho risolto, mettendo l'output di script1 in pipe con:
 
        sed 's/\x1b\[[0-9;]*m//g'
 
che mi sembra piú elegante del giochino che avevo fatto con awk, ed inoltre
filtra anche comandi ansi multipli nella stessa riga.
 
Quindi il loop "for" di script2 del mio caso diventa:
 
for IP in $(script1 | sed 's/\x1b\[[0-9;]*m//g')
do
...
...
 
Mi segno il giochetto, valido anche in altri casi simili.
 
-- 
+---------------------------------------------------------------------------+
|     Il Pascal e' un linguaggio giocattolo fatto per insegnare la          |
|     programmazione ai matematici.                                         |
+-----#20-------------------------------------Diamanti di saggezza.---------+


 
Certo,la soluzione l' avevi scritta nel post iniziale, ma sei sempre tu 
che avevi chiesto una soluzione piu pulita
 

 ...
 
Ti sino state già date due soluzioni facili e pulite per risolvere 
la cosa. Lasciando stare i dettagli implementativi (è una stupidata
implementarle) tu le hai rifiutate adducendo scuse da bambino 
capriccioso.
 
È tuo diritto fare i capricci quindi ti propongo una terza soluzione,
usare la versione originale del tuo script senza immondizia infilata
nell'otput. Certo per me è una stupidata avere due versioni dello 
stesso programma quando con  uno switch ed un if puoi risolvere
ma comunque c'è l'ipotesi che sei un bambino capriccioso.
 
Se poi usi la scusa che il tuo vecchio script è cancellato è non 
hai backup l'ipotesi bambino capriccioso diventa certezza insieme 
alla certezza dell'ipotesi utonto che non fa i backup.
 

 Mi segno il giochetto, valido anche in altri casi simili.
 
  La soluzione più elegante, a mio avviso, è di includere, nello script che
genera l'output che contiene le sequenze di escape per i colori, un test per
verificare che lo script sia o no collegato ad un terminale, e una verifica
che il terminale in uso supporti i colori.  Traggo il seguito da un vecchio
script di bash, che era stato pensato per stampare sul terminale stringhe in
grassetto solo se il terminale lo supportava.
 
$ cat ~/bin/prova_grassetto.sh
#!/bin/bash
 
BOLD=''
NORM=''
 
# Permetti l'espansione degli alias nella shell non interattiva
shopt -s expand_aliases
 
# Se non ho un terminaloide collegato all'uscita, neanche ci provo
if tty -s
then # Il comando infocmp (del pacchetto ncurses) serve per ottenere le
     # proprietà del terminale.  Se c'è, si usa per fighettizzare i
     # messaggi. Se non c'è pazienza, si va di dumb-terminal.
     if command -v infocmp > /dev/null
     then if test -n "$(infocmp -1I "$TERM" | grep 'bold=\\E\[1m,')"
          then alias echo='echo -e'
               NORM="\033[0m"
               BOLD="\033[1m"
          fi
     fi
fi
 
echo Stringa di ${BOLD}prova${NORM} testo ${BOLD}grassetto${NORM} nel
terminale $TERM su $(tty)
 
$ prova_grassetto.sh
Stringa di *prova* testo *grassetto* nel terminale xterm-256color su /dev/pts/2
$ prova_grassetto.sh | cat
Stringa di prova testo grassetto nel terminale xterm-256color su non è un tty
$
 
 
  Nel tuo caso dovresti usare:
 
infocmp -1I "$TERM" | grep 'colors#'
 
e variabili per i vari colori, come:
 
WHITE_ON_RED='\033[97;101m'
BLACK_ON_CYAN='\033[30;106m'
MAGENTA='\033[95m'
NORMAL='\033[0m'
BLUE_ON_YELLOW='\033[34;103m' # Arghh!! :-)
 
  Il test per verificare che l'uscita sia collegata ad un terminale (tty -s)
può essere sostituito da test -c "/proc/$$/fd/1", evitandoti così anche
l'esecuzione del comando /bin/tty.
 
  Leggermente complesso, ma ad alto valore old-Unix-school geek!  :-)
 
 
  Ciao,
 
 
-- 
Alessandro Selli 
http://alessandro.route-add.net
 
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.