서브셸 내부에서 배열 매개변수 수정

서브셸 내부에서 배열 매개변수 수정

shift서브쉘 내부에서 배열 매개변수에 값을 할당하거나 할당하는 것이 가능합니까 ?

예제 코드:

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

답변1

현재의 복사본에서 코드의 일부를 실행하는 것이 서브쉘의 핵심입니다.쉘 실행 환경(자세한 내용은POSIX 사양for sh), 원본을 보존하기 위해 서브쉘에서 수행된 변수에 대한 모든 변경 사항은 서브쉘 종료 후에 손실된다는 것이 요점입니다.

전통적으로 이는 프로세스를 분기하는 셸에 의해 수행되며 부모가 종료를 기다리는 동안 자식에서 코드를 실행합니다.

POSIX는 이를 요구하지 않으며 ksh93은 최소한 (...)프로세스를 피할 수 있는 경우 프로세스를 포크하지 않고 서브셸 반환 시 원래 환경을 신중하게 복원하여 서브셸을 구현합니다(일부 경우에는 제대로 수행하지 못하는 경우도 있음).

zsh대부분의 다른 쉘과 마찬가지로 프로세스를 포크합니다. (...)서브쉘이 스크립트의 마지막 명령 인 경우와 같이 최적화에는 예외가 있습니다 zsh -c.

$ 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

위의 21085 프로세스는 를 실행하고 zsh, 서브쉘을 해석하고, 심지어 마지막 ps명령을 실행하기도 했습니다.

해당 최적화를 무효화하기 위해 a를 설정하는 것으로 충분합니다. trap요점은 zsh가 서브 쉘이 반환된 후 쉘에 의해 아무것도 실행되지 않을 것이라고 보장할 수 있는 경우에만 수행된다는 것입니다.

gdb하위 프로세스가 상위 프로세스의 변수 값을 변경할 수 있으려면 해당 프로세스에 연결하고 해당 프로세스에 코드를 삽입하여 해당 프로세스의 내부 메모리 구조를 변경하는 등 의 작업을 수행해야 합니다 .

서브쉘에 의해 정의된 배열의 값을 얻으려면 해당 정의를 상위 쉘에 전달하는 서브쉘이 필요합니다. 예를 들어 다음을 통해 이루어질 수 있습니다.

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

그런 다음 typeset출력됩니다 typeset -a arr=( a b c )(또는 typeset -g -a arr=( a b c )함수 내에서 호출되는 경우). 일단 evaluated되면 동일한 변수가 상위 변수에 생성됩니다.

그건 그렇고, 대신에:

shift arr

나는 다음을 사용할 것이다:

shift 1 arr

또는:

arr[1]=()

코드 조각은 배열 변수로 선언되었는지 여부에 따라 다른 것( vs ) shift arr을 의미하므로 모호합니다 . 을 사용하면 원하는 것이 전자라는 것이 더 분명해집니다.shift 1 arrshift arr argvarrshift 1 arr

답변2

서브셸은 다른 프로세스이므로 상위 프로세스를 수정할 수 없습니다.

관련 정보