Bash
Estructuras de Control
Buscar..
Sintaxis
- ["$ 1" = "$ 2"] #A "[" el corchete es en realidad un comando. Por eso requiere un espacio antes y después.
- test "$ 1" = "$ 2" #Test es un sinónimo para el comando "["
Parámetros
Parámetro a [o prueba | Detalles |
---|---|
Operadores de archivos | Detalles |
-e "$file" | Devuelve true si el archivo existe. |
-d "$file" | Devuelve true si el archivo existe y es un directorio. |
-f "$file" | Devuelve verdadero si el archivo existe y es un archivo normal |
-h "$file" | Devuelve true si el archivo existe y es un enlace simbólico |
Comparadores de cuerdas | Detalles |
-z "$str" | Verdad si la longitud de la cadena es cero |
-n "$str | Verdad si la longitud de la cadena no es cero |
"$str" = "$str2" | Verdad si la cadena $ str es igual a la cadena $ str2. No es lo mejor para los enteros. Puede funcionar pero será inconsitente. |
"$str" != "$str2" | Cierto si las cuerdas no son iguales |
Comparadores de enteros | Detalles |
"$int1" -eq "$int2" | Verdad si los enteros son iguales |
"$int1" -ne "$int2" | Verdad si los enteros no son iguales |
"$int1" -gt "$int2" | Verdad si int1 es mayor que int 2 |
"$int1" -ge "$int2" | Verdadero si int1 es mayor o igual que int2 |
"$int1" -lt "$int2" | Verdad si int1 es menor que int 2 |
"$int1" -le "$int2" | Verdad si int1 es menor o igual que int2 |
Observaciones
Hay muchos parámetros de comparación disponibles en bash. No todos están listados aquí.
Si declaración
if [[ $1 -eq 1 ]]; then
echo "1 was passed in the first parameter"
elif [[ $1 -gt 2 ]]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
El cierre de fi
es necesario, pero se pueden omitir las cláusulas elif
y / o else
.
Los puntos y coma antes de then
son sintaxis estándar para combinar dos comandos en una sola línea; solo se pueden omitir si then
se mueve a la siguiente línea.
Es importante entender que los corchetes [[
no son parte de la sintaxis, pero se tratan como un comando; es el código de salida de este comando que se está probando. Por lo tanto, siempre debe incluir espacios alrededor de los corchetes.
Esto también significa que el resultado de cualquier comando puede ser probado. Si el código de salida del comando es un cero, la declaración se considera verdadera.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Las expresiones matemáticas, cuando se colocan entre paréntesis dobles, también devuelven 0 o 1 de la misma manera, y también se pueden probar:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
También puede encontrar if
declaraciones con corchetes simples. Estos se definen en el estándar POSIX y se garantiza que funcionarán en todas las carcasas compatibles con POSIX, incluyendo Bash. La sintaxis es muy similar a la de Bash:
if [ "$1" -eq 1 ]; then
echo "1 was passed in the first parameter"
elif [ "$1" -gt 2 ]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Mientras bucle
#! /bin/bash
i=0
while [ $i -lt 5 ] #While i is less than 5
do
echo "i is currently $i"
i=$[$i+1] #Not the lack of spaces around the brackets. This makes it a not a test expression
done #ends the loop
Observe que hay espacios alrededor de los paréntesis durante la prueba (después de la instrucción while). Estos espacios son necesarios.
Este bucle produce:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
En bucle
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
Otros comandos pueden generar sentencias para pasar. Consulte el ejemplo de "Uso de For Loop para iterar sobre números".
Esto produce:
1
test
3
Usando For Loop para enumerar Iterar sobre números
#! /bin/bash
for i in {1..10}; do # {1..10} expands to "1 2 3 4 5 6 7 8 9 10"
echo $i
done
Esto da como resultado lo siguiente:
1
2
3
4
5
6
7
8
8
10
Para bucle con sintaxis estilo C
El formato básico de estilo C for
bucle es:
for (( variable assignment; condition; iteration process ))
Notas:
- La asignación de la variable dentro de C-style
for
bucle puede contener espacios a diferencia de la asignación habitual - Las variables dentro del estilo C
for
bucle no están precedidas por$
.
Ejemplo:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
También podemos procesar múltiples variables dentro de C-style for
loop:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Hasta Loop
Hasta que el bucle se ejecute hasta que la condición sea verdadera
i=5
until [[ i -eq 10 ]]; do #Checks if i=10
echo "i=$i" #Print the value of i
i=$((i+1)) #Increment i by 1
done
Salida:
i=5
i=6
i=7
i=8
i=9
Cuando i
a 10, la condición en hasta que el bucle se vuelve verdadero y el bucle termina.
continuar y romper
Ejemplo para continuar
for i in [series]
do
command 1
command 2
if (condition) # Condition to jump over command 3
continue # skip to the next value in "series"
fi
command 3
done
Ejemplo para romper
for i in [series]
do
command 4
if (condition) # Condition to break the loop
then
command 5 # Command if the loop needs to be broken
break
fi
command 6 # Command to run if the "condition" is never true
done
Bucle sobre una matriz
for
bucle:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
O
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
while
bucle:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
O
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Ruptura de bucle
Romper bucle múltiple:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break 2
done
done
Salida:
a
a
Romper un solo bucle:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Salida:
a
a
b
a
c
a
d
a
e
a
f
a
Cambiar declaración con el caso
Con la declaración del case
puede hacer coincidir los valores con una variable.
El argumento pasado al case
se expande e intenta hacer coincidir con cada patrón.
Si se encuentra una coincidencia, los comandos hasta ;;
son ejecutados.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Los patrones no son expresiones regulares sino que coinciden con los patrones de shell (también conocido como globs).
Para Loop sin un parámetro de lista de palabras
for arg; do
echo arg=$arg
done
Un bucle for
sin un parámetro de lista de palabras iterará sobre los parámetros posicionales. En otras palabras, el ejemplo anterior es equivalente a este código:
for arg in "$@"; do
echo arg=$arg
done
En otras palabras, si te encuentras escribiendo for i in "$@"; do ...; done
, acaba de caer el in
parte, y escribir simplemente for i; do ...; done
Ejecución condicional de listas de comandos
Cómo utilizar la ejecución condicional de las listas de comandos.
Cualquier comando, expresión o función incorporada, así como cualquier comando externo o secuencia de comandos, se pueden ejecutar condicionalmente usando &&
(and) y ||
(o) operadores.
Por ejemplo, esto solo imprimirá el directorio actual si el comando cd
fue exitoso.
cd my_directory && pwd
Del mismo modo, esto se cerrará si el comando cd
falla, previniendo una catástrofe:
cd my_directory || exit
rm -rf *
Al combinar varias declaraciones de esta manera, es importante recordar que (a diferencia de muchos lenguajes de estilo C), estos operadores no tienen precedencia y son asociativos por la izquierda .
Por lo tanto, esta declaración funcionará como se espera ...
cd my_directory && pwd || echo "No such directory"
- Si el
cd
tiene éxito,&& pwd
ejecuta y se imprime el nombre del directorio de trabajo actual. A menos quepwd
falle (una rareza) el|| echo ...
no será ejecutado. - Si el
cd
falla, se omitirá&& pwd
y el|| echo ...
correrá
Pero esto no (si estás pensando if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Si el
cd
falla, se omite el&& ls
y el|| echo ...
se ejecuta. - Si el
cd
tiene éxito, se ejecuta&& ls
.- Si la
ls
tiene éxito, la|| echo ...
se ignora (hasta ahora tan bueno) - PERO ... si la
ls
falla, el|| echo ...
también será ejecutado.Es el
ls
, no elcd
, que es el comando anterior .
- Si la
¿Por qué usar la ejecución condicional de las listas de comandos?
La ejecución condicional es mucho más rápida que if...then
pero su principal ventaja es permitir que las funciones y los scripts salgan antes, o "cortocircuito".
A diferencia de muchos lenguajes como C
donde la memoria se asigna explícitamente para estructuras y variables y similares (y, por lo tanto, debe ser desasignado), bash
maneja esto bajo las coberturas. En la mayoría de los casos, no tenemos que limpiar nada antes de abandonar la función. Una declaración de return
desasignará todo lo local a la función y la ejecución de recolección en la dirección de devolución en la pila.
Regresar de las funciones o salir de los scripts lo antes posible puede mejorar significativamente el rendimiento y reducir la carga del sistema al evitar la ejecución innecesaria de código. Por ejemplo...
my_function () {
### ALWAYS CHECK THE RETURN CODE
# one argument required. "" evaluates to false(1)
[[ "$1" ]] || return 1
# work with the argument. exit on failure
do_something_with "$1" || return 1
do_something_else || return 1
# Success! no failures detected, or we wouldn't be here
return 0
}