Estoy estudiando scripts de shell con bash y necesito saber la diferencia entre (...)
y {...}
. ¿Cómo se selecciona entre los dos al escribir un guión?
Estoy estudiando scripts de shell con bash y necesito saber la diferencia entre (...)
y {...}
. ¿Cómo se selecciona entre los dos al escribir un guión?
Respuestas:
Si desea que los efectos secundarios de la lista de comandos afecten a su shell actual , use {...}
Si desea descartar cualquier efecto secundario, use(...)
Por ejemplo, podría usar una subshell si:
$IFS
algunos comandos, pero no quiero modificar $IFS
globalmente el shell actualcd
en algún lugar, pero no quiero cambiar el $PWD
para el shell actualVale la pena señalar que los paréntesis se pueden usar en una definición de función:
uso normal: llaves: el cuerpo de la función se ejecuta en el shell actual; los efectos secundarios permanecen después de que se completa la función
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
uso inusual: paréntesis: el cuerpo de la función se ejecuta en una subshell; los efectos secundarios desaparecen cuando sale la subshell
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
palabra clave ayuda mucho a limpiar esa contaminación.
pwd; (count_tmp); pwd;
De la documentación oficial de bash :
()
( list )
Al colocar una lista de comandos entre paréntesis, se crea un entorno de subshell y cada uno de los comandos de la lista se ejecuta en esa subshell. Dado que la lista se ejecuta en una subshell, las asignaciones de variables no permanecen vigentes una vez que se completa la subshell.
{}
{ list; }
Colocar una lista de comandos entre llaves hace que la lista se ejecute en el contexto actual del shell. No se crea ninguna subshell. Se requiere la siguiente lista de punto y coma (o nueva línea).
El código en '{}' se ejecuta en el subproceso / proceso / entorno actual y se conservan los cambios, para decirlo de manera más sucinta, el código se ejecuta en el ámbito actual.
El código en '()' se ejecuta dentro de un proceso secundario separado de bash que se descarta después de la ejecución. Este proceso secundario a menudo se conoce como un subconjunto y se puede considerar como un nuevo ámbito secundario.
Como ejemplo, considere lo siguiente ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
Observe que en el primer ejemplo con '{}' la variable aún se establece incluso después del cierre '}', mientras que en el ejemplo con '()' la variable no se establece fuera del alcance de '()'.
(...)
se utilizan para ejecutar código en un sub-shell. El código usado entre bewteen {...}
no se usará en un sub-shell.