2012-09-11 28 views
17

No puedo entender esto. ¿Por qué se usaría /dev/null como entrada en una declaración if? ¿Cuál es el uso de < /dev/null en lo siguiente?if()</ dev/null

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

I (piensa) entiendo que > /dev/null 2>&1 sólo se utiliza para suprimir cualquier salida de ambos stdout y stderr.

Respuesta

15

Si $PROG es un programa que se espera que el aporte de stdin, la secuencia de comandos podría estancar siempre esperando para que escriba algo en. El uso de < /dev/null es proporcionar una entrada vacía para un programa de este tipo. Tiene razón sobre > y 2>&1.

Este fragmento de script se está comprobando para ver si $PROG --version sale con un estado 0 (correcto) y luego ejecuta ese programa sin ninguna marca. Si $PROG --version falla, la secuencia de comandos repite "falló" y sale.

+0

Gracias. Todavía no estoy seguro de lo útil que es esto si sé qué '$ PROG' es y sé que' PROG --version' no está esperando la entrada. Por ejemplo, 'PROG = autoconf' es uno donde vi esto.Y sé que 'autoconf --version' no está esperando la entrada. ¿Sigue siendo útil en este caso? –

+0

@Carl Norum, ¿podría el 'if ('$ PROG --version')' (con corchetes angulares) usarse aquí para ejecutar el comando y, por lo tanto, no es necesario ''///null'? – fduff

+0

¿Soportes angulares? –

13

Creo que se está preguntando por qué la redirección está fuera de los paréntesis.

En esta línea:

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

los paréntesis no son parte de la sintaxis de la instrucción if; solo especifican la agrupación de comandos. (Me tomó un momento para recordar que a mí mismo, en CSH/tcsh, paréntesis son parte de la sintaxis de una instrucción if.)

Por ejemplo, esto:

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

producirá esta salida :

ONE 
TWO 

En este caso, puesto que $PROG --version es un solo comando, los paréntesis son innecesarias (a menos $PROG se expande a más de un comando, pero eso es poco probable).

Por lo que la redirección no se aplica a la declaración if; se aplica al $PROG --version. El propósito es no proporcionar ninguna entrada (como si estuviese leyendo desde un archivo vacío) al $PROG, y descartar cualquier cosa que escriba en stdout o stderr. Si $PROG es un comando que lee de stdin, incluso cuando se invoca con --version, entonces sin la redirección de entrada podría colgar esperando la entrada del teclado.

El script asume que es seguro invocar $PROG (cualquiera que sea) solo si $PROG --version no produce un error.

Tenga en cuenta que puede aplicar la redirección a una sentencia if:

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

Esto redirige la entrada y salida de test_command, something, y something_else.

+0

¡Gracias por una gran respuesta! De hecho, estaba confundido con respecto a los paréntesis. Gracias por desglosarlo y dar ejemplos. Gran explicación –