¿Cómo se relaciona eso con la respuesta aceptada dada en Error de operador inesperado ? Obtuve el mismo error al usar [ "$1" == "on" ]. Cambiar esto a ["$ 1" = "on"] resolvió el problema.
Piotr Dobrogost
78
Los espacios son necesarios.
TAAPSogeking
66
@JohnFeminella Al escribir en un script bash, debe tener un solo =y no dos.
user13107
73
Vale la pena señalar que no puede usar [ $x -eq "valid" ]. -eqes el operador de comparación para enteros, no cadenas.
craq
2
@Alex, ¿en qué casos (si alguna vez) necesito usar el patrón ["x$yes" == "xyes"], que es el prefijo de la variable y el literal de cadena con un x? ¿Es una reliquia de los viejos tiempos o es realmente necesario en algunas situaciones?
Gracias por la comparación de orden alfabético de cadenas
shadi
Mi problema era que $arealmente lo " "rodeaba como parte del valor literal de la cadena, por lo tanto, tuve que usar el carácter de escape $bpara comparar los valores. Pude encontrar esto después de ejecutar bash -x ./script.sh, el indicador -x le permite ver el valor de cada ejecución y ayuda en la depuración.
ShahNewazKhan
Tenga en cuenta que la comparación de orden alfabético no está estandarizada por POSIX, por lo que no se garantiza que funcione en plataformas no GNU / shells no bash. Solo las operaciones en pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html tienen garantía de ser portátiles.
Charles Duffy
62
Para comparar cadenas con comodines use
if[["$stringA"==*$stringB*]];then# Do something hereelse# Do Something herefi
¡Es importante que los comodines solo se puedan usar en el lado derecho! También tenga en cuenta lo que falta "alrededor de los comodines. (por cierto: +1 para comodines!)
Scz
66
La expansión $stringBdebe ser citado (y, de paso, la izquierda no tiene que ser citado): if [[ $stringA = *"$stringB"* ]]; then.
gniourf_gniourf
Estoy tratando de usar la misma lógica comodín para el nombre de archivo en la ruta del archivo. Pero no está funcionando para mí. Probé todas las cadenas comodín diferentes que se proporcionan aquí. pero siempre va al caso más. stringA en mi caso es una ruta de archivo / tmp / file y stringB es "archivo".
lluvia
35
Tengo que estar en desacuerdo con uno de los comentarios en un punto:
["$x"=="valid"]&& echo "valid"|| echo "invalid"
No, eso no es una línea loca loca
Es solo que parece uno para, hmm, los no iniciados ...
Utiliza patrones comunes como lenguaje, en cierto modo;
Y después de que aprendiste el idioma.
En realidad, es bueno leer
Es una expresión lógica simple, con una parte especial: evaluación perezosa de los operadores lógicos.
["$x"=="valid"]&& echo "valid"|| echo "invalid"
Cada parte es una expresión lógica; el primero puede ser verdadero o falso, los otros dos siempre son verdaderos.
(["$x"=="valid"]&&
echo "valid")||
echo "invalid"
Ahora, cuando se evalúa, se comprueba el primero. Si es falso, el segundo operando de la lógica y&& después no es relevante. El primero no es cierto, por lo que no puede ser el primero y el segundo, de todos modos.
Ahora, en este caso es el primer lado de la lógica o|| falso, pero podría ser cierto si el otro lado, la tercera parte, es verdadero.
Entonces se evaluará la tercera parte, principalmente escribiendo el mensaje como un efecto secundario. (Tiene el resultado 0verdadero, que no usamos aquí)
Los otros casos son similares, pero más simples, ¡y lo prometo! son - pueden ser - fáciles de leer!
(No tengo uno, pero creo que ser un veterano de UNIX con barba gris ayuda mucho con esto).
Por ... && ... || ...lo general, está mal visto (lo siento veterano de Unix de barba gris, te has equivocado todo este tiempo), ya que no es semánticamente equivalente a if ... then ... else .... No se preocupe, esta es una trampa común .
gniourf_gniourf
66
@gniourf_gniourf OP no está mal, ni es probable que sean ignorantes como sugieres. ... && ... || ...es un patrón perfectamente válido y un idioma común de bash. Su uso prescribe conocimientos previos (lo que puede ser bueno tener en cuenta si hay principiantes en la audiencia), pero OP tiene el pelo para demostrar que saben cómo evitar las tapas de alcantarillas abiertas.
ebpa
3
@ebpa ¿Qué sucede si la declaración que sigue a && devuelve un valor falso? La ejecución continuará hasta la siguiente declaración || ? Si es así, eso está mal y tal vez es lo que sugiere gniourf
TSG
44
Pensé que echo era solo un ejemplo. La declaración que sigue a && aún podría devolver un valor distinto de cero
TSG
2
@gniourf_gniourf +1 por publicar el enlace a Bash Pitfalls! ¡Muy útil!
@ytpillai, es equivalencia. Tenga en cuenta que puede tener patrones separados por |, antes de ). La indeclaración es equivalente a thenen ifdeclaraciones. Podrías argumentar que funciona sobre una lista de patrones, donde cada lista tiene su propia declaración de qué hacer, si vienes de Python. No como substring in string, sino más bien for item in list. Use a *como su última declaración si desea una elsecondición. Regresa en el primer encuentro.
mazunki
18
El siguiente script lee un archivo llamado "testonthis" línea por línea y luego compara cada línea con una cadena simple, una cadena con caracteres especiales y una expresión regular. Si no coincide, el script imprimirá la línea, de lo contrario no.
El espacio en Bash es muy importante. Entonces lo siguiente funcionará:
["$LINE"!="table_name"]
Pero lo siguiente no lo hará:
["$LINE"!="table_name"]
Así que por favor use como está:
cat testonthis |while read LINE
doif["$LINE"!="table_name"]&&["$LINE"!="--------------------------------"]&&[["$LINE"=~[^[:space:]]]]&&[["$LINE"!= SQL*]];then
echo $LINE
fidone
Use este enfoque para revisar un archivo. Es decir, elimine la UUoC entre otras cosas.
Fedorqui 'así que deja de dañar'
No es importante por bashsino porque [es en realidad un binario externo (como en which [rendimientos algo así /usr/bin/[)
Patrick Bergner
11
Probablemente usaría coincidencias regexp si la entrada tiene solo unas pocas entradas válidas. Por ejemplo, solo "iniciar" y "detener" son acciones válidas.
Tenga en cuenta que pongo en minúscula la variable $ACTIONusando las comas dobles. También tenga en cuenta que esto no funcionará en versiones de bash demasiado antiguas.
para mí (mac GNU bash versión 4.4.12 (1) -release x86_64-apple-darwin17.0.0), tengo que usar if [ "$a"="$b" ]o no funciona ... no puedo tener espacios alrededor de los iguales
espectro
1
Lo hice de esta manera que es compatible con Bash y Dash (sh):
testOutput="my test"
pattern="my"case $testOutput in(*"$pattern"*)
echo "if there is a match"
exit 1;;(*)! echo there is no coincidence!;;esac
Respuestas:
Usar variables en declaraciones if
Si desea hacer algo cuando no coinciden, reemplace
=
con!=
. Puede leer más sobre las operaciones de cadena y las operaciones aritméticas en su documentación respectiva.¿Por qué usamos citas
$x
?Desea las comillas
$x
, porque si está vacío, su script Bash encuentra un error de sintaxis como se ve a continuación:Uso no estándar del
==
operadorTenga en cuenta que Bash permite
==
ser utilizado para igualdad con[
, pero esto no es estándar .Utilice el primer caso en el que las comillas
$x
son opcionales:o use el segundo caso:
fuente
[ "$1" == "on" ]
. Cambiar esto a ["$ 1" = "on"] resolvió el problema.=
y no dos.[ $x -eq "valid" ]
.-eq
es el operador de comparación para enteros, no cadenas.["x$yes" == "xyes"]
, que es el prefijo de la variable y el literal de cadena con unx
? ¿Es una reliquia de los viejos tiempos o es realmente necesario en algunas situaciones?O, si no necesita otra cláusula:
fuente
echo
puede fallar.[ "$X" == "valid" ] || ( echo invalid && false ) && echo "valid"
.{ echo invalid && false; }
es más eficiente que( echo invalid && false )
, ya que evita pagar una subshell innecesaria.Notas:
if
y[
y]
son importantes>
y<
son operadores de redireccionamiento, así que escapa con\>
y\<
respectivamente para cadenas.fuente
$a
realmente lo" "
rodeaba como parte del valor literal de la cadena, por lo tanto, tuve que usar el carácter de escape$b
para comparar los valores. Pude encontrar esto después de ejecutarbash -x ./script.sh
, el indicador -x le permite ver el valor de cada ejecución y ayuda en la depuración.Para comparar cadenas con comodines use
fuente
"
alrededor de los comodines. (por cierto: +1 para comodines!)$stringB
debe ser citado (y, de paso, la izquierda no tiene que ser citado):if [[ $stringA = *"$stringB"* ]]; then
.Tengo que estar en desacuerdo con uno de los comentarios en un punto:
No, eso no es una línea loca loca
Es solo que parece uno para, hmm, los no iniciados ...
Utiliza patrones comunes como lenguaje, en cierto modo;
Y después de que aprendiste el idioma.
En realidad, es bueno leer
Es una expresión lógica simple, con una parte especial: evaluación perezosa de los operadores lógicos.
Cada parte es una expresión lógica; el primero puede ser verdadero o falso, los otros dos siempre son verdaderos.
Ahora, cuando se evalúa, se comprueba el primero. Si es falso, el segundo operando de la lógica y
&&
después no es relevante. El primero no es cierto, por lo que no puede ser el primero y el segundo, de todos modos.Ahora, en este caso es el primer lado de la lógica o
||
falso, pero podría ser cierto si el otro lado, la tercera parte, es verdadero.Entonces se evaluará la tercera parte, principalmente escribiendo el mensaje como un efecto secundario. (Tiene el resultado
0
verdadero, que no usamos aquí)Los otros casos son similares, pero más simples, ¡y lo prometo! son - pueden ser - fáciles de leer!
(No tengo uno, pero creo que ser un veterano de UNIX con barba gris ayuda mucho con esto).
fuente
... && ... || ...
lo general, está mal visto (lo siento veterano de Unix de barba gris, te has equivocado todo este tiempo), ya que no es semánticamente equivalente aif ... then ... else ...
. No se preocupe, esta es una trampa común .... && ... || ...
es un patrón perfectamente válido y un idioma común de bash. Su uso prescribe conocimientos previos (lo que puede ser bueno tener en cuenta si hay principiantes en la audiencia), pero OP tiene el pelo para demostrar que saben cómo evitar las tapas de alcantarillas abiertas.también puedes usar use case / esac
fuente
|
, antes de)
. Lain
declaración es equivalente athen
enif
declaraciones. Podrías argumentar que funciona sobre una lista de patrones, donde cada lista tiene su propia declaración de qué hacer, si vienes de Python. No comosubstring in string
, sino más bienfor item in list
. Use a*
como su última declaración si desea unaelse
condición. Regresa en el primer encuentro.El siguiente script lee un archivo llamado "testonthis" línea por línea y luego compara cada línea con una cadena simple, una cadena con caracteres especiales y una expresión regular. Si no coincide, el script imprimirá la línea, de lo contrario no.
El espacio en Bash es muy importante. Entonces lo siguiente funcionará:
Pero lo siguiente no lo hará:
Así que por favor use como está:
fuente
bash
sino porque[
es en realidad un binario externo (como enwhich [
rendimientos algo así/usr/bin/[
)Probablemente usaría coincidencias regexp si la entrada tiene solo unas pocas entradas válidas. Por ejemplo, solo "iniciar" y "detener" son acciones válidas.
Tenga en cuenta que pongo en minúscula la variable
$ACTION
usando las comas dobles. También tenga en cuenta que esto no funcionará en versiones de bash demasiado antiguas.fuente
Bash 4+ ejemplos. Nota: no usar comillas causará problemas cuando las palabras contengan espacios, etc. Comillas siempre en Bash, IMO.
Aquí hay algunos ejemplos en Bash 4+:
Ejemplo 1, verifique 'sí' en la cadena (no distingue entre mayúsculas y minúsculas):
Ejemplo 2, verifique 'sí' en la cadena (no distingue entre mayúsculas y minúsculas):
Ejemplo 3, verifique 'sí' en la cadena (distingue entre mayúsculas y minúsculas):
Ejemplo 4, verifique 'sí' en la cadena (distingue entre mayúsculas y minúsculas):
Ejemplo 5, coincidencia exacta (mayúsculas y minúsculas):
Ejemplo 6, coincidencia exacta (sin distinción entre mayúsculas y minúsculas):
Ejemplo 7, coincidencia exacta:
Disfrutar.
fuente
if [ "$a"="$b" ]
o no funciona ... no puedo tener espacios alrededor de los igualesLo hice de esta manera que es compatible con Bash y Dash (sh):
fuente
(
no usarlo?