2012-09-11 10 views
17

Non riesco a capirlo. Perché lo /dev/null deve essere utilizzato come input per una dichiarazione if? Qual è l'uso di < /dev/null nel seguente?if()</ dev/null

if ($PROG --version) </dev/null> /dev/null 2>&1; then 
     $PROG 
else 
     echo "failed" 
     exit 1 
fi 

I (credo) ho capito che > /dev/null 2>&1 è solo usato per sopprimere qualsiasi uscita da entrambi stdout e stderr.

risposta

15

Se $PROG è un programma che si aspetta input da stdin, lo script potrebbe arrestarsi per sempre in attesa di digitare qualcosa in. L'uso di < /dev/null è quello di fornire un input vuoto per un programma del genere. Hai ragione riguardo allo > e allo 2>&1.

Questo snippet di script sta verificando se $PROG --version chiude con uno stato 0 (esito positivo), quindi esegue quel programma senza alcun flag. Se $PROG --version fallisce, lo script fa eco a "fallito" ed esce.

+0

Grazie. Non sono ancora sicuro di quanto sia utile se so cosa sia '$ PROG' e so che' PROG --version' non aspetta input. Ad esempio, 'PROG = autoconf' è uno dove ho visto questo.E so che 'autoconf --version' non sta aspettando input. È ancora utile in questo caso? –

+0

@Carl Norum, potrebbe il 'if ('$ PROG --version')' (con parentesi angolari) essere usato qui per eseguire il comando e quindi non c'è bisogno di ' fduff

+0

Parentesi angolari? –

13

Penso che ti stia chiedendo perché il reindirizzamento è fuori dalle parentesi.

In questa linea:

if ($PROG --version) </dev/null> /dev/null 2>&1; then 

le parentesi non sono parte della sintassi della dichiarazione if; specificano semplicemente il raggruppamento dei comandi. (Mi ci volle un momento per ricordare che me stesso, in csh/tcsh, parentesi sono parte della sintassi di un if dichiarazione.)

Ad esempio, questo:

(echo one ; echo two) | tr a-z A-Z 

produrrà questo output :

ONE 
TWO 

In questo caso, dal momento che $PROG --version è un unico comando, le parentesi non sono necessarie (a meno che non $PROG espande a più di un comando, ma questo è improbabile).

Quindi il reindirizzamento non si applica all'istruzione if; si applica a $PROG --version. Lo scopo è di non fornire input (come se si leggesse da un file vuoto) a $PROG e di scartare qualsiasi cosa scriva su stdout o stderr. Se $PROG è un comando che legge da stdin, anche se invocato con --version, quindi senza il reindirizzamento dell'input potrebbe bloccarsi in attesa di input da tastiera.

Lo script presuppone che è sicuro invocare $PROG (qualunque esso sia) solo se $PROG --version non produce un errore.

Si noti che è possibile applicare il reindirizzamento ad un'istruzione if:

if test_command ; then 
    something 
else 
    something_else 
fi </dev/null> /dev/null 2>&1 

Questo reindirizza input e output per test_command, something, esomething_else.

+0

Grazie per l'ottima risposta! Ero davvero confuso riguardo le parentesi. Grazie per averlo scomposto per me e per dare degli esempi. Ottima spiegazione. –