2015-03-01 18 views
6

Provo a impostare la variabile che ottiene l'indirizzo IP dell'interfaccia da ifconfig e lo legge in seguito. Ma quando eseguo un comando echo, la variabile è ancora vuota. Si prega di guardare il mio codice:Impostazione della variabile in bash -c

/usr/bin/bash -c "HOST_IPS=$(/usr/bin/ifconfig | /usr/bin/awk 'BEGIN {cnt=0} {if($0 ~ /inet/&& cnt==1) {print $2} cnt++}'); echo $HOST_IPS" 

Ma/bin/fine lavoro eco con lo stesso comando:

/usr/bin/bash -c "echo $(/usr/bin/ifconfig | /usr/bin/awk 'BEGIN {cnt=0} {if($0 ~ /inet/&& cnt==1) {print $2} cnt++}')" 
+0

1. Dove vedi '/ bin/echo'? 2. Poiché le tue virgolette esterne sono doppie virgolette, devi sfuggire _all_ i simboli '$' all'interno. –

risposta

6

Hai per evitare il segno $ nel comando echo finale, o la variabile $HOST_IPS verrà sostituita nella stringa di comando prima che venga generata la subshell:

/usr/bin/bash -c "HOST_IPS=$(/usr/bin/ifconfig | /usr/bin/awk 'BEGIN {cnt=0} {if($0 ~ /inet/&& cnt==1) {print $2} cnt++}'); echo \$HOST_IPS" 

Per una visibilità più immediata:

#             v-- insert backslash here 
/usr/bin/bash -c "HOST_IPS=$(same as before); echo \$HOST_IPS" 

Contrariamente a @ di gniourf_gniourf commento, non è effettivamente necessario per sfuggire gli altri segni del dollaro. Tuttavia, come scritto, la sostituzione di comando non viene eseguita dalla subshell (!); il suo risultato è sostituito nella stringa di comando che viene passata alla subshell. Le chiamate

mypid() { echo $$; } 
bash -c "pid=$(mypid); echo \$pid; mypid" 

dimostrano il modo in cui funziona: sarà una volta stampare il PID della shell genitore e una volta che si lamentano che mypid non è un comando noto perché la subshell non conosce la funzione.

Poiché è improbabile che il comando ifconfig | awk nella shell parent sia un problema, è possibile lasciare invariata la parte di sostituzione del comando. Se è importante che il comando venga eseguito dalla subshell, dovrai anche scappare da tutte le cose.

+0

grazie! Funziona! – d0xin

+0

@Wintermute Ci si sbaglia su/proc/self. [link] (https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/3/html/Reference_Guide/s1-proc-directories.html) – nawK

+0

Oh, a destra - readlink genera il proprio processo. Hmm ... come dimostrare, allora? Dammi un momento. – Wintermute

0

Con /usr/bin/bash si avvia una subshell. Al termine della shell, tutte le impostazioni nella shell vengono perse.
Il seguente sub si trova nella subshell e ha perso prima di essere eco:

/usr/bin/bash -c sub=1; echo $sub 

Vuoi impostare una variabile in una subshell, uso stdout per il trasporto del valore:

sub=$(/usr/bin/bash -c "echo 1"); echo $sub 
0

Dalla domanda e dall'esempio, il tuo compito non richiede di lasciare l'ambiente corrente, quindi non è necessario avviarne uno nuovo e preoccuparsi dei dati persi.

HOST_IPS=(); 
while read -r; 
    do [[ $REPLY =~ "inet "([^/]*) ]] && HOST_IPS+=(${BASH_REMATCH[1]}); 
done < <(ip -f inet address show) 

Se si desidera mantenere un elenco di interfaccia indirizzi IP è possibile elaborare l'output di ip (o ifconfig) nella shell corrente senza chiamare awk.