Modificar el parámetro de matriz desde el interior del subshell

Modificar el parámetro de matriz desde el interior del subshell

¿Es posible shiftasignar un valor a un parámetro de matriz desde dentro de una subcapa?

Código de ejemplo:

arr=(a b c)
(shift arr)
echo $arr
# prints: a b c
# should print: b c

Respuesta1

El objetivo de los subshells es ejecutar una parte del código en una copia del actual.entorno de ejecución de shell(ver detalles enla especificación POSIXfor sh), para preservar el original, por lo que el punto es que cualquier cambio en las variables realizadas en el subnivel se perderá después de la terminación del subnivel.

Tradicionalmente, esto se hace mediante el shell que bifurca un proceso y ejecuta el código en el hijo mientras el padre espera su terminación.

POSIX no exige eso y ksh93 al menos implementa (...)subcapas restaurando cuidadosamente el entorno original al regresar la subcapa sin bifurcar un proceso si eso se puede evitar (aunque a veces no lo hace correctamente en algunos casos extremos).

zshbifurca un proceso para eso como la mayoría de los otros shells. Hay excepciones para la optimización, como cuando un (...)subshell es el último comando en un zsh -cscript:

$ zsh -c 'zmodload zsh/system; echo $$; (echo $sysparams[pid]; ps; ps)'
21085
21085
    PID TTY          TIME CMD
   1839 pts/4    00:00:00 zsh
  21085 pts/4    00:00:00 zsh
  21086 pts/4    00:00:00 ps
    PID TTY          TIME CMD
   1839 pts/4    00:00:00 zsh
  21085 pts/4    00:00:00 ps

Es el mismo proceso 21085 anterior que ejecutó zsh, interpretó el subshell e incluso ejecutó el último pscomando.

Es suficiente configurar a trappara invalidar esa optimización, el punto es que solo se hace si zsh puede garantizar que el shell no ejecutará nada después de que regrese el subshell.

Para que el proceso hijo pueda cambiar el valor de una variable en el proceso padre, necesitaría hacer cosas como adjuntarse gdba ese proceso e inyectar código en él para cambiar las estructuras de la memoria interna en ese proceso.

Si desea obtener el valor de una matriz definida por un subshell, necesitaría que el subshell pase su definición al padre. Esto podría ser, por ejemplo, a través de:

eval "$(
  # also a subshell using $(...)
  arr=( a b c )
  typeset -p arr
)"

Luego typesetgenerará typeset -a arr=( a b c )(o typeset -g -a arr=( a b c )si se llama dentro de una función), que una vez evalactivada hará que se cree la misma variable en el padre.

Por cierto, en lugar de:

shift arr

Yo usaría:

shift 1 arr

o:

arr[1]=()

El shift arrfragmento de código es ambiguo ya que significa cosas diferentes ( shift 1 arrvs shift arr argv) dependiendo de si arrse declara como una variable de matriz o no. El uso shift 1 arrhace que sea más obvio que lo que quieres es lo primero.

Respuesta2

Una subcapa es un proceso diferente, no puede modificar el proceso principal.

información relacionada