¿Cuál es el significado de if [ -n "$(what voltdb 2> /dev/null)" ];?

¿Cuál es el significado de if [ -n "$(what voltdb 2> /dev/null)" ];?

Tengo conocimientos muy básicos de Linux y ahora estoy intentando analizar algunos scripts de Shell. Veo esta línea en uno de los scripts:

if [ -n "$(which voltdb 2> /dev/null)" ];

Sé que /dev/null es el depósito de bits y el que imprime la ruta que se habría ejecutado si hubiera ejecutado voltdb en la línea de comando. Además, toda la línea es obviamente una declaración if. Pero aquí estoy confundido acerca de muchas otras cosas.

  1. ¿Por qué se compara 2 con /dev/null? Estos parecen tipos incompatibles.
  2. ¿Qué hace el modificador -n? Estoy acostumbrado a usar modificadores como rm -r nombre de archivo pero -n no parece emparejarse con ningún comando
  3. ¿Qué hacen los corchetes? Parecen significar algo más aquí que en esta expresión.¿Cuál es el significado de esta expresión de prueba []?

Básicamente, ¿qué hace esta línea? Hay demasiadas incógnitas en esto para mí, por lo que es un poco como escuchar una oración en un idioma extranjero y perderse tantas palabras que no puedes captar la estructura básica.

Respuesta1

Están sucediendo muchas cosas en ese fragmento de código. Trabajando de adentro hacia afuera:

which voltdb 2> /dev/null- El comando ejecutado aquí es which. whichcuando se invoque, buscará todas las entradas en la PATHvariable de entorno para encontrar un comando llamado "voltdb". Si encuentra un archivo ejecutable llamado "voltdb" en uno de los directorios nombrados en PATH, imprimirá el nombre completo del voltdbarchivo ejecutable.

Para responder a su número 1, el "2>" es un ejemplo de redirección. Cada proceso Unix/Linux/*BSD tiene 3 entradas y salidas estándar, 0 es stdin, 1 es stdout, 2 es stderr. Los programas destinados a ejecutarse en la línea de comandos normalmente imprimen mensajes de error en stderr. Entonces, "2> /dev/null" no compara numéricamente 2 con "/dev/null", envía cualquier whichsalida de error a /dev/null, un archivo especial que simplemente consume cualquier entrada y devuelve 0 bytes de salida.

Fuera de eso, la $(...)construcción significa "ejecutar el comando adjunto y sustituir léxicamente cualquier salida aquí, entre '$(' y ')'". Eso es sustitución de salida, algo que hacen los programas shell.

Fuera de la sustitución de salida, el fragmento lo hace if [ -n "something" ];, donde "algo" es lo que whichse habría impreso. El "si" es una construcción de flujo de control del shell, que hace que se ejecute un bloque de código cuando la canalización de comandos después del "si" sale con un estado de "éxito".

En realidad, es [un ejecutable que analiza los argumentos de la línea de comandos hasta el archivo ]. El indicador "-n" generalmente significa "verdadero en el siguiente argumento de longitud de cadena distinta de cero". Esa es la respuesta a tus preguntas número 2 y 3. La [ ... ]construcción da respuestas verdaderas (salida con código de éxito) o falsas (salida con código de error) a algunas condiciones lógicas, en este caso "longitud de cadena distinta de cero".

En última instancia, ese fragmento ejecutaría la cláusula "verdadera" de un flujo de control if-then-fi o if-then-else-fi cuando la RUTA de ese shell tiene un directorio con un voltdbarchivo ejecutable.

Respuesta2

Ese código está haciendo lo siguiente:

if [ -n "...." ];

La declaración if es verdadera si el resultado del código cuando se ejecuta entre comillas dobles está vacío.

El código entre comillas dobles:

$(which voltdb 2> /dev/null)

Ejecuta el which voltdbcomando y redirige cualquier resultado de este comando que ocurra en STDERR (error estándar) a /dev/null. Básicamente no nos interesa, así que lo ignoramos.

Los resultados de which voltdbdevolverán la ruta a cualquier ejecutable en su RUTA que coincida con la cadena voltdb.

Ejemplo

$ which time
/usr/bin/time

$ which time 2> /dev/null
/usr/bin/time

Qué pasa con la 2>?

2>es una notación abreviada para redirigir la salida de uno de loscorrientesque se configura automáticamente para un programa cuando se ejecuta. Las corrientes son las siguientes:

  • 0 - entrada estándar (también conocida como STDIN)
  • 1 - salida estándar (también conocida como STDOUT)
  • 2 - error estándar (también conocido como STDERR)

Entonces, si desea tomar la salida de STDERR y deshacerse de ella:

$ which time 2> /dev/null

Si desea tomar la salida de STDOUT y redirigirla a STDERR:

información relacionada