Pagina 1 di 1

Help script Bash

Inviato: ven 17 feb 2012, 20:48
da AndreaIphone
Ciao,
sto iniziando ora a programmare in bash script.

Ho un ciclo:

Codice: Seleziona tutto

#!/bin/sh

check=0

cat nodelist | grep -v nanos | awk -F ';' '{print $1}' | while read nodo
do
        if [ "$nodo" = "torpedo" ];then
                check=1
        fi

done

echo $check
Quando esco dal ciclo, se la condizione si avvera la variabile check dovrebbe assumere il valore 1, invece all'uscita del ciclo perde il valore assegnato e mantiene quello iniziale (in questo caso 0)

qualcuno mi da una dritta????

Grazie mille

Re: Help script Bash

Inviato: sab 18 feb 2012, 9:59
da targzeta
Ciao e benvenuto. Quando posti del codice o l'output di un programma, usa sempre i tag 'code' di phpBB per rendere più leggibile il post. Guarda il tuo post precedente (tasto 'edit' o 'modifica') che te l'ho modificato io in questo senso.

Per la tua domanda. Intanto puoi evitare di fare un 'cat|grep' poiché grep, di suo, prende tranquillamente come parametro un file. Nel tuo caso quindi questi due comandi sono equivalenti:

Codice: Seleziona tutto

cat nodelist | grep -v nanos

Codice: Seleziona tutto

grep -v nanos nodelist
Il codice che hai scritto è semplice e non dovrebbe presentare problemi. L'unica cosa che penso è che la variabile 'nodo' non prende mai il valore che ti aspetti e quindi 'check' non viene mai assegnata ad 1. Che quest'ultima perda il suo valore è da escludere. Metti un:

Codice: Seleziona tutto

echo 'ciao'
prima di settare check a 1, così capisci se la condizione è stata verificata.

Emanuele

Re: Help script Bash

Inviato: sab 18 feb 2012, 11:12
da 414N
Ciao e benvenuto anche da parte mia.
Sottoscrivo quanto già affermato da spina e aggiungo che, messo giù così, il codice non potrà mai funzionare: non hai considerato che, ogni volta che metti in pipe (|) dei comandi, questi vengono eseguiti in sottoprocessi indipendenti dal processo genitore che li ha lanciati.
Nel tuo codice, il processo genitore (chiamiamolo p0) inizializza la variable check a 0 (nel suo ambiente), poi viene creato un nuovo processo con una copia dell'ambiente (p1) che esegue il cat (superfluo come già detto da spina), dopodiché ne viene creato un altro (p2) che esegue grep, un'altro (p3) che esegue awk e un'altro (p4) che esegue il while. Tutti i processi p1-4 possiedono una copia della variabile check, ma non "puntano" più alla variabile check di p0. Quindi, quando in p4 poni check a 1 lo fai solo per la copia di check presente nell'ambiente di p4. È per questo che, una volta uscito dai sottoprocessi al termine del ciclo e tornato in p0, check è ancora a 0.
Per ottenere quello che vuoi fare, puoi agire in maniera diversa:

Codice: Seleziona tutto

#!/bin/sh

# Pongo lo standard output del comando racchiuso tra `` (si ottengono tramite ALTGR+') nella variabile CHECK. In questo caso il comando è costituito da una lista di comandi interconnessi tramite pipe.
CHECK=`grep -v nanos nodelist | awk -F ';' '{print $1}' | while read NODO
    do
            if [ "$NODO" = "torpedo" ];then
		# Stampo qualcosa su standard output. Cosa non ha importanza in questo contesto, tanto in seguito si controlla solo se CHECK è stata impostata a qualcosa o no
                    echo OKCQMWCNQCIUQNCQC
            fi

    done`

# Controllo se CHECK è impostata, il che significa che la echo all'interno del while è stata raggiunta.
if [ $CHECK ]
then
	echo "torpedo trovato"
else
	echo "torpedo non trovato"
fi
Per approfondire l'argomento dei sottoprocessi avviati dalla shell, puoi dare un'occhiata a questa pagina.
PS: l'usanza comune è di usare nomi di variabili tutti in maiuscolo in ambito di bash scripting, per farli risaltare rispetto ai comandi o alle builtin della shell.

Re: Help script Bash

Inviato: sab 18 feb 2012, 11:21
da targzeta
Cavolo 414N, hai ragione!!! Dal man della bash:

Codice: Seleziona tutto

 Pipelines
...
       Each command in a pipeline is executed as a separate process (i.e., in a subshell).
Quindi questa mia affermazione:
spina ha scritto:...
L'unica cosa che penso è che la variabile 'nodo' non prende mai il valore che ti aspetti e quindi 'check' non viene mai assegnata ad 1. Che quest'ultima perda il suo valore è da escludere.
...
è sbagliata!!!

Emanuele

Re: Help script Bash

Inviato: sab 18 feb 2012, 15:06
da masalapianta
aggiungo che per motivi di prestazioni, quando possibile, è meglio delegare l'uso di cicli a comandi come grep, piuttosto che farli nello script:

Codice: Seleziona tutto

if $(grep -v nanos nodelist | grep "torpedo" >/dev/null); then echo "1";else echo 0;fi

Re: Help script Bash

Inviato: sab 18 feb 2012, 16:43
da 414N
masalapianta ha scritto:aggiungo che per motivi di prestazioni, quando possibile, è meglio delegare l'uso di cicli a comandi come grep, piuttosto che farli nello script:

Codice: Seleziona tutto

if $(grep -v nanos nodelist | grep "torpedo" >/dev/null); then echo "1";else echo 0;fi
Ottimo consiglio. In questo modo, con due processi grep si fa tutto il lavoro e non c'è neanche più il problema di accesso a variabili locali di sotto-processi che aveva messo in difficoltà AndreaIphone.
Aggiungo solo, per completezza, che le due forme

Codice: Seleziona tutto

$(comando)
e

Codice: Seleziona tutto

`comando`
sono praticamente equivalenti (nella bash, la vecchia forma coi backquote `` tratta in modo letterale il carattere backslash "\" salvo in casi particolari).