Help script Bash

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
AndreaIphone
Linux 0.x
Linux 0.x
Messaggi: 1
Iscritto il: ven 17 feb 2012, 20:45

Help script Bash

Messaggio 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

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Help script Bash

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
414N
Iper Master
Iper Master
Messaggi: 2922
Iscritto il: mer 13 feb 2008, 16:19
Slackware: 15.0
Kernel: 5.15.19
Desktop: KDE5
Località: Bulagna
Contatta:

Re: Help script Bash

Messaggio 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.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6629
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Help script Bash

Messaggio 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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
masalapianta
Iper Master
Iper Master
Messaggi: 2775
Iscritto il: lun 25 lug 2005, 0:00
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian
Località: Roma
Contatta:

Re: Help script Bash

Messaggio 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

Avatar utente
414N
Iper Master
Iper Master
Messaggi: 2922
Iscritto il: mer 13 feb 2008, 16:19
Slackware: 15.0
Kernel: 5.15.19
Desktop: KDE5
Località: Bulagna
Contatta:

Re: Help script Bash

Messaggio 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).

Rispondi