¿Cuál es la diferencia entre [y [[en Bash?

Miré en la página man bash y el [[ dice que usa expresiones condicionales. Luego miré en la sección Expresiones condicionales y enumera los mismos operadores que test (y [ ).

Entonces me pregunto, ¿cuál es la diferencia entre [ y [[ en Bash?

[[ es la mejora de bash para el [ comando. Tiene varias mejoras que lo hacen una mejor opción si escribe scripts que se dirigen a bash. Mis favoritos son:

  1. Es una característica sintáctica del shell, por lo que tiene un comportamiento especial que [ no tiene. Ya no tiene que citar variables como enojado porque [[ maneja cadenas vacías y cadenas con espacios en blanco de forma más intuitiva. Por ejemplo, con [ tienes que escribir

     if [ -f "$file" ] 

    manejar correctamente cadenas vacías o nombres de archivos con espacios en ellos. Con [[ las comillas son innecesarias:

     if [[ -f $file ]] 
  2. Como es una característica sintáctica, te permite usar && y || operadores para pruebas booleanas y < y > para comparaciones de cadenas. [ No puedo hacer esto porque es un comando regular y && , || , < y > no se pasan a los comandos regulares como argumentos de línea de comandos.

  3. Tiene un maravilloso =~ operador para hacer coincidencias de expresiones regulares. Con [ podrías escribir

     if [ "$answer" = y -o "$answer" = yes ] 

    Con [[ puedes escribir esto como

     if [[ $answer =~ ^y(es)?$ ]] 

    Incluso le permite acceder a los grupos capturados que almacena en BASH_REMATCH . Por ejemplo, ${BASH_REMATCH[1]} sería "es" si escribió un "sí" completo arriba.

  4. Obtienes la coincidencia de patrones también conocida como globbing gratis. Tal vez eres menos estricto sobre cómo escribir "sí". Tal vez estés bien si el usuario escribe y-anything. Te tengo cubierto:

     if [[ $ANSWER = y* ]] 

Tenga en cuenta que es una extensión de bash, por lo que si está escribiendo scripts compatibles con sh, deberá seguir con [ . Asegúrese de tener la línea #!/bin/bash shebang para su script si usa corchetes dobles.

Ver también

  • Bash FAQ - "¿Cuál es la diferencia entre prueba, [y [[??"
  • Prácticas Bash - Bash Tests
  • Error del servidor: ¿Cuál es la diferencia entre los corchetes dobles e individuales en bash?
  • [ es lo mismo que la test integrada, y funciona como el binario de test (prueba de hombre)
    • funciona aproximadamente igual que [ en todos los otros shells basados ​​en sh en muchos entornos tipo UNIX
    • solo admite una sola condición. Múltiples pruebas con bash && y || los operadores deben estar en corchetes separados.
    • no admite de forma nativa un operador “no”. Para invertir una condición, use a ! fuera del primer paréntesis para usar la función del intérprete de comandos para invertir los valores de retorno del comando.
    • == y != son comparaciones literales de cadenas
  • [[ es una fiesta
    • es específico de bash, aunque otros shells pueden haber implementado construcciones similares. No lo esperes en un sh de UNIX de la vieja escuela.
    • == y != aplicar reglas de coincidencia de patrón de bash, ver “Coincidencia de patrón” en man bash
    • tiene un operador de correspondencia =~ regex
    • permite el uso de paréntesis y ! , && , y || operadores lógicos entre paréntesis para combinar subexpresiones

Aparte de eso, son bastante similares: la mayoría de las pruebas individuales funcionan de manera idéntica entre ellas, las cosas solo se vuelven interesantes cuando se necesitan combinar diferentes pruebas con operaciones lógicas AND / O / NOT.

En bash, contrariamente a [ , [[ evita la división de palabras de los valores variables.

La diferencia más importante será la claridad de tu código. Sí, sí, lo dicho anteriormente es cierto, pero [[]] alinea su código con lo que cabría esperar en los lenguajes de alto nivel, especialmente con respecto a AND ( && ), OR ( || ) y NOT ( ! ) operadores. Por lo tanto, cuando te mueves entre sistemas e idiomas, podrás interpretar guiones más rápido, lo que te facilitará la vida. Obtenga lo esencial de una buena referencia de UNIX / Linux. Puede encontrar algunos de los elementos esenciales para ser útil en ciertas circunstancias, pero siempre apreciará un código claro . ¿Qué fragmento de script preferirías leer? Incluso fuera de contexto, la primera opción es más fácil de leer y entender.


 if [[ -d $newDir && -n $(echo $newDir | grep "^${webRootParent}") && -n $(echo $newDir | grep '/$') ]] then ... 

o

 if [ -d "$newDir" -a -n $(echo "$newDir" | grep "^${webRootParent}") -a -n $(echo "$newDir" | grep '/$') ] then ...