2013-07-10 14 views
14

Ho un piccolo pezzo di codice che verifica la validità indirizzo IP:Come utilizzare il codice di ritorno di bash in condizionale?

function valid_ip() 
{ 
    local ip=$1 
    local stat=1 

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 
     OIFS=$IFS 
     IFS='.' 
     ip=($ip) 
     IFS=$OIFS 
     if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ 
      && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then 
      stat=1 
     else 
      stat=0 
     fi 
    fi 
    return $stat 
} 

Ma io sto avendo problemi con il suo utilizzo in condizionali bash. Ho provato molte tecniche per testare il suo valore di ritorno ma la maggior parte di esse non ha successo su di me.

if [[ !$(valid_ip $IP) ]]; then 

if [[ $(valid_ip IP) -eq 1 ]]; then 

ecc. Ecc. Qualcuno può suggerire cosa devo fare qui?

EDIT

Seguendo i suggerimenti che ho usato qualcosa come:

if valid_ip "$IP" ; then 
     ... do stuff 
    else 
     perr "IP: \"$IP\" is not a valid IP address" 
    fi 

e ottengo errori come

IP: "10.9.205.228" non è un IP valido indirizzo

risposta

12

Il codice di ritorno è disponibile nel parametro speciale $? dopo l'uscita del comando. In genere, è sufficiente utilizzare quando si vuole salvare il suo valore prima di eseguire un altro comando:

valid_ip "$IP1" 
status1=$? 
valid_ip "$IP2" 
if [ $status1 -eq 0 ] || [ $? -eq 0 ]; then 

o se è necessario distinguere tra diversi stati diversi da zero:

valid_ip "$IP" 
case $? in 
    1) echo valid_IP failed because of foo ;; 
    2) echo valid_IP failed because of bar ;; 
    0) echo Success ;; 
esac 

In caso contrario, lasciate che i vari operatori controllano implicitamente:

if valid_ip "$IP"; then 
    echo "OK" 
fi 

valid_IP "$IP" && echo "OK" 

Ecco un modo semplice, idiomatica di scrivere valid_ip:

valid_ip() { 
    local ip=$1 
    [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && { 
     IFS='.' read a b c d <<< "$ip" 
     ((a < 255 && b < 255 && c < 255 && d << 255)) 
    } 
} 

Ci sono due espressioni, il [[...]] e { ... }; i due sono uniti da &&. Se il primo fallisce, allora valid_ip fallisce. Se supera, viene valutata la seconda espressione (l'istruzione composta). Lo read divide la stringa in quattro variabili e ciascuna viene testata separatamente all'interno dell'espressione aritmetica. Se tutte le vere sono vere, allora il successo è ((...)), il che significa che l'elenco && ha esito positivo, il che significa che valid_ip ha esito positivo. Non è necessario memorizzare o restituire codici di ritorno espliciti.

+0

Si prega di dare un'occhiata alla mia modifica. – Patryk

+3

La shell interpreta 0 come esito positivo e diverso da zero come errore, opposto alla consueta interpretazione booleana.'valid_IP' dovrebbe restituire 0 se l'indirizzo IP è valido, e 1 altrimenti. – chepner

+0

solo il problema è che questo non funzionerà con 'set -e' –

8

Nessun parentesi necessari se lo stato di uscita viene ispezionata:

if valid_ip $IP ; then 
    ... 

basta chiamare la funzione nel modo in cui si chiamare qualsiasi altro comando.

+0

Si prega di dare un'occhiata alla mia modifica. – Patryk

+0

@Patryk: nota che i comandi restituiscono 0 in caso di successo. Restituisce 0 per un IP valido. – choroba

+0

Ma ho pensato che $ {ip [0]} -le 255' è per controllare che il primo ottetto sia minore o uguale a 255 e così via per gli ottetti rimanenti. – Patryk