Comparación de cadenas en bash. [[: extraviado


166

Estoy tratando de comparar cadenas en bash. Ya encontré una respuesta sobre cómo hacerlo en stackoverflow . En el script que estoy intentando, estoy usando el código enviado por Adam en la pregunta mencionada:

#!/bin/bash
string='My string';

if [[ "$string" == *My* ]]
then
  echo "It's there!";
fi

needle='y s'
if [[ "$string" == *"$needle"* ]]; then
  echo "haystack '$string' contains needle '$needle'"
fi

También probé el enfoque de ubuntuforums que puedes encontrar en la segunda publicación

if [[ $var =~ regexp ]]; then
  #do something
fi

En ambos casos recibo un error:

[[: not found

¿Qué estoy haciendo mal?


Podría hacerlo mal, pero usar un solo corchete siempre funcionó para mí.
Markus Unterwaditzer

1
¿Qué /bin/bash --versionimprime?
themel

44
[no funcionará en este caso, porque no admite patrones.
Ansgar Wiechers

Respuestas:


158

[[es un bash-builtin. Tu /bin/bashno parece ser una fiesta real.

De un comentario:

Agregar #!/bin/bashen la parte superior del archivo


si
escribo

55
¿Obtienes el mismo resultado cuando corres /bin/bash -c "type [["?
Ansgar Wiechers

43
Esto me sucedió porque olvidé agregar #!/bin/bashen la parte superior de mi archivo
morpático

12
Pasé a mí porque ejecuté el script con shmucha frustración. Ahora solo tengo que rehacer todo lo que deshice antes de encontrar esta respuesta.
Louis Loudog Trottier

174

¿Cómo estás ejecutando tu script? Si lo hicieras con

$ sh myscript

Deberías intentarlo:

$ bash myscript

o, si el script es ejecutable:

$ ./myscript

sh y bash son dos conchas diferentes . Mientras que en el primer caso pasa su guión como argumento al intérprete sh, en el segundo caso decide en la primera línea qué intérprete se utilizará.


obtuve permiso denegado de esta manera. con sudo ./myscript su comando no encontrado
user1581900

11
hacer chmod + x myscript , luego ejecutar de nuevo, no necesitas sudo
Akos K

2
¿Cómo estás invocando tu guión?
Akos K

Como dijiste. normalmente lo llamo con '$ sh myscipt.sh'. 2da vez después de hacer chmod + x myscript.sh lo llamé con ./myscript.sh
user1581900

55
Se espera el error cuando ejecuta el script vía sh myscript.sh, porque /bin/shemula un shell Bourne donde [[no está integrado. Sin embargo, ejecutar el script vía ./script.shno debería producir un error, porque en ese caso el shebang debería hacer /bin/bashque se use.
Ansgar Wiechers

81

Es la primera línea en tu script:

#!/bin/bash

o

#!/bin/sh

el shell sh produce estos mensajes de error, no bash


1
¡También me faltaba la primera línea para producir el error que mencionó el autor!
Anónimo

14

Tuve este problema al instalar Heroku Toolbelt

Así es como resolví el problema.

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 ago 15  2012 /bin/sh -> dash

Como puede ver, / bin / sh es un enlace a "guión" (no bash), y [[es azucar sintáctico bash. Así que acabo de reemplazar el enlace a / bin / bash. ¡Tenga cuidado al usar rm como este en su sistema!

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh

66
Anular el valor predeterminado shpara su distribución es mal aconsejado en mi humilde opinión. Un shell con el que se ejecuta shdebería funcionar dash; si no es así, eso es un error en el guión. Si necesita bashfunciones, use bash, no sh.
tripleee

44
esto suena terrible
tbh

2
Estoy de acuerdo, fue solo una solución fea. Una solución similar pero mejor sería usar update-alternatives(en debian-based-linux) como este justinconover.wordpress.com/2012/05/14/… pero al final, sería lo mismo.
jperelli

13

Como @Ansgar mencionó, [[es un bashism, es decir, integrado en Bash y no está disponible para otros shells. Si quieres que tu script sea portátil, úsalo [. Las comparaciones también necesitarán una sintaxis diferente: cambiar ==a =.


Comprobé un poco con Ubuntu 16.04 y (sh ->) dash 0.5.8-2.1ubuntu2 y descubrí que [funciona bien en combinación con "-eq" y similares. Se puede encontrar información similar sobre operadores de comparación para este contexto aquí: stackoverflow.com/questions/10849297/… - Realicé una búsqueda adicional con el operador de evaluación (()) como se recomienda en el siguiente enlace, pero eso pareció fallar para mis cambios invasivos mínimos / o / necesitaría un nivel mucho más profundo de cambios de código. softpanorama.org/Scripting/Shellorama/Control_structures/…
Alexander Stohr

3

Especifique bash en lugar de sh cuando ejecute el script. Personalmente noté que son diferentes en Ubuntu 12.10:

bash script.sh arg0 ... argn


¡Esto me lo arregló!
Djamillah
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.