Estoy confundido por el uso de corchetes, paréntesis, llaves en Bash, así como por la diferencia entre sus formas dobles o simples. ¿Hay una explicación clara?
En Bash, test
y [
son conchas incorporadas.
El paréntesis doble , que es una palabra clave de shell, permite una funcionalidad adicional. Por ejemplo, puede utilizar &&
y ||
en lugar de -a
y -o
y hay un operador de expresión regular coincidente =~
.
Además, en una prueba simple, los corchetes dobles parecen evaluarse mucho más rápido que los simples.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Las llaves, además de delimitar un nombre de variable, se usan para la expansión de parámetros, por lo que puede hacer cosas como:
Truncar el contenido de una variable
$ var="abcde"; echo ${var%d*}
abc
Hacer sustituciones similares a sed
$ var="abcde"; echo ${var/de/12}
abc12
Use un valor predeterminado
$ default="hello"; unset var; echo ${var:-$default}
hello
y varios mas
Además, las expansiones de llaves crean listas de cadenas que generalmente se repiten en bucles:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Tenga en cuenta que las características iniciales de incremento e cero no estaban disponibles antes de Bash 4.
Gracias a gboffi por recordarme sobre expansiones de aparatos ortopédicos.
Los paréntesis dobles se usan para operaciones aritméticas :
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
y le permiten omitir los signos de dólar en las variables de enteros y matrices e incluyen espacios alrededor de los operadores para facilitar la lectura.
Los corchetes individuales también se usan para los índices de matriz :
array[4]="hello"
element=${array[index]}
Se requieren llaves para las referencias de matriz (¿la mayoría / todas?) En el lado derecho.
El comentario de ephemient me recordó que los paréntesis también se usan para subcapas. Y que se usan para crear matrices.
array=(1 2 3)
echo ${array[1]}
2
:
.$[expression]
:; esta es la sintaxis de expresión aritmética antigua y obsoleta para la sintaxis preferida más nueva:$((expression))
bash
creación de secuencias, como se menciona periféricamente a continuación ( stackoverflow.com/a/8552128/2749397 ) Como me gustaría comentar un poco esta característica (ya que no lo mencionaste ;-) I ' Me estoy tomando la libertad de usar la respuesta más votada como vehículo ... Dos ejemplos de literales de secuencia:echo {01..12}
->01 02 03 04 05 06 07 08 09 10 11 12
(observe el cero inicial);echo {C..Q}
->C D E F G H I J K L M N O P Q
. Su uso principal es en bucles, por ejemplo,for cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}
-> "01 03 05 07 09 11". Gracias por el recordatorio sobre las secuencias. Lo agregaré a mi respuesta.Un solo paréntesis (
[
) generalmente llama a un programa llamado[
;man test
oman [
para más información Ejemplo:El paréntesis doble (
[[
) hace lo mismo (básicamente) que un paréntesis simple, pero es un bash incorporado.Los paréntesis (
()
) se usan para crear una subshell. Por ejemplo:Como puede ver, el subshell le permitió realizar operaciones sin afectar el entorno del shell actual.
(a) Las llaves (
{}
) se utilizan para identificar inequívocamente variables. Ejemplo:(b) Las llaves también se utilizan para ejecutar una secuencia de comandos en el contexto actual del shell, por ejemplo
Sin
( )
embargo, hay una sutil diferencia sintáctica con (ver referencia de bash ); en esencia, un punto y coma;
después de la última orden entre llaves es una necesidad, y las llaves{
,}
debe estar rodeado por espacios.fuente
[
realidad es una función integrada en Bash, pero se supone que debe actuar/bin/[
como algo opuesto a la función[[
integrada.[[
tiene características diferentes, como operaciones más lógicas y diferentes roles de citas. Además: los paréntesis simples también se usan para matrices, sustitución de procesos y globos extendidos; los paréntesis dobles se usan para la aritmética; Las llaves{}
se utilizan para la agrupación de comandos o multitudes de tipos de expansión de parámetros o expansión de llaves o expansión de secuencia. Estoy seguro de que he perdido algunos otros usos también ...if [ $VARIABLE == abcdef ]
es un bashismo que, aunque funciona, probablemente debería evitarse; explícitamente use bash (if [[ ...==...]]
) o deje en claro que está usando el condicional más tradicional (if [ "$VARIABLE" = "abcdef" ]
). Podría decirse que los scripts deberían comenzar de la manera más simple y portátil posible, hasta que realmente necesiten características específicas de bash (por una razón u otra). Pero en cualquier caso, la intención debe ser clara; "=" y "==" y "[[" y "[" funcionan de manera diferente y su uso debe ser coherente.[ "$var" = ".."]
lugar de==
, mientras que en C asignaría en lugar de probar (y es una causa bastante común de errores) ... ¿por qué no 'ttest
utilizar==
en lugar de=
? ¿alguien sabe?/usr/bin/[
no es un enlace simbólico al/usr/bin/test
, y más: ¡estos programas incluso tienen algunos tamaños diferentes!)
es parte de lacase
sintaxis de la declaración para finalizar una línea de caso. No tiene un paréntesis de apertura. Esto me sorprendió la primera vez que lo vi.Soportes
[1] http://wiki.bash-hackers.org/scripting/obsolete
Llaves
Paréntesis
Paréntesis dobles
fuente
$(varname)
no está relacionado con la sintaxis bash. Es parte de la sintaxis de Makefile .$(varname)
no tiene relación con la sintaxis bash en su caso.Solo quería agregarlos desde TLDP :
fuente
echo ${#ARRAY}
muestra tres, porque el primer elementoARRAY
contiene tres caracteres, no porque contiene tres elementos! Para imprimir el número de elementos useecho ${#ARRAY[@]}
.${TEST:-test}
es igual a$TEST
si la variableTEST
existe, de lo contrario, simplemente devuelve la cadena "prueba". Hay otra versión que hace aún más:${TEST:=test}
--- que también equivale a$TEST
si TEST existe, pero siempre que no existe, crea la variableTEST
y asigna un valor "prueba" y también se convierte en el valor de toda la expresión.La diferencia entre test , [ y [[ se explica con gran detalle en BashFAQ .
Y la conclusión:
fuente
Paréntesis en la definición de funciones
Los paréntesis
()
se utilizan en la definición de funciones:Esa es la razón por la que debe escapar del paréntesis incluso en los parámetros de comando:
fuente
unset -f echo
. Verhelp unset
.fuente