script - operadores logicos linux bash
Operadores lógicos simples en Bash (5)
Tengo un par de variables y quiero verificar la siguiente condición (escrita en palabras, luego mi intento fallido en bash scripting):
if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then
do something
done.
Y en mi intento fallido, se me ocurrió:
if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) );
then
scale=0.05
fi
Aquí está el código para la versión corta de la declaración if-then-else:
( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"
Preste atención a lo siguiente:
||
y & operandos dentro si la condición (es decir, entre paréntesis redondos) son operandos lógicos (o / y)||
y & operandos fuera si la condición significa entonces / else
Prácticamente la declaración dice:
if (a = 1 o b = 2) luego "ok" else "nok"
Lo que has escrito en realidad casi funciona (funcionaría si todas las variables fueran números), pero no es una forma idiomática en absoluto.
-
(…)
paréntesis indican una subshell . Lo que hay dentro de ellos no es una expresión como en muchos otros idiomas. Es una lista de comandos (al igual que paréntesis externos). Estos comandos se ejecutan en un subproceso separado, por lo que cualquier redirección, asignación, etc. realizada dentro de los paréntesis no tiene ningún efecto fuera del paréntesis.- Con un signo de dólar inicial,
$(…)
es una sustitución de comando : hay un comando entre paréntesis, y el resultado del comando se usa como parte de la línea de comando (después de expansiones adicionales a menos que la sustitución se realice entre comillas dobles, pero esa es otra historia ).
- Con un signo de dólar inicial,
-
{ … }
llaves son como paréntesis porque agrupan comandos, pero solo influyen en el análisis, no en la agrupación. El programax=2; { x=4; }; echo $x
x=2; { x=4; }; echo $x
x=2; { x=4; }; echo $x
imprime 4, mientras quex=2; (x=4); echo $x
x=2; (x=4); echo $x
x=2; (x=4); echo $x
prints 2. (También los refuerzos requieren espacios alrededor de ellos y un punto y coma antes del cierre, mientras que los paréntesis no. Eso es solo una peculiaridad de sintaxis).- Con un signo de dólar líder,
${VAR}
es una expansión de parámetros , que se expande al valor de una variable, con posibles transformaciones adicionales.
- Con un signo de dólar líder,
-
((…))
paréntesis doble rodea una instrucción aritmética , es decir, un cálculo en enteros, con una sintaxis similar a otros lenguajes de programación. Esta sintaxis se usa principalmente para asignaciones y en condicionales.- La misma sintaxis se usa en las expresiones aritméticas
$((…))
, que se expanden al valor entero de la expresión.
- La misma sintaxis se usa en las expresiones aritméticas
-
[[ … ]]
corchetes dobles rodean las expresiones condicionales . Las expresiones condicionales se basan principalmente en operators como-n $variable
para comprobar si una variable está vacía y-e $file
para probar si existe un archivo. También hay operadores de igualdad de cadenas:"$string1" = "$string2"
(tenga en cuenta que el lado derecho es un patrón, por ejemplo[[ $foo = a* ]]
prueba si$foo
comienza cona
rato[[ $foo = "a*" ]]
prueba si$foo
es exactamentea*
), ¡y lo familiar!
,&&
y||
operadores para negación, conjunción y disyunción, así como paréntesis para agrupar. Tenga en cuenta que necesita un espacio alrededor de cada operador (por ejemplo[[ "$x" = "$y" ]]
, no), y un espacio o un carácter como[[ "$x"="$y" ]]
;
tanto dentro como fuera de los corchetes (por ejemplo,[[ -n $foo ]]
, no).[[-n $foo]]
-
[ … ]
corchetes individuales son una forma alternativa de expresiones condicionales con más peculiaridades (pero más antiguas y más portátiles). No escriba ninguno por ahora; comienza a preocuparte por ellos cuando encuentres guiones que los contengan.
Esta es la forma idiomática de escribir tu prueba en bash:
if [[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]; then
Si necesita portabilidad para otros shells, esta sería la forma (tenga en cuenta las cotizaciones adicionales y los conjuntos de corchetes por separado alrededor de cada prueba individual):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
Una versión muy portátil (incluso para el shell bourne heredado):
if [ "$varA" = 1 -a /( "$varB" = "t1" -o "$varB" = "t2" /) ]
then do-something
fi
Esto tiene la cualidad adicional de ejecutar solo un subproceso a lo sumo (que es el proceso ''[''), cualquiera que sea el sabor del shell.
Reemplace "=" con "-eq" si las variables contienen valores numéricos, por ejemplo
- 3 -eq 03 es cierto, pero
- 3 = 03 es falso. (comparación de cadenas)
muy cerca
if [[ $varA -eq 1 ]] && [[ $varB == ''t1'' || $varC == ''t2'' ]];
then
scale=0.05
fi
Deberia trabajar.
descomponiéndolo
[[ $varA -eq 1 ]]
es una comparación entera donde como
$varB == ''t1''
es una comparación de cadenas. de lo contrario, solo estoy agrupando las comparaciones correctamente.
Los corchetes dobles delimitan una expresión condicional. Y, creo que lo siguiente es una buena lectura sobre el tema: "(IBM) prueba Demystify, [, [[, (y, si, entonces, otro)"
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
echo STR is empty but should have a value.
fi