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

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

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 )함수 내에서 호출되는 경우) 일단 eval사용되면 상위 변수에 동일한 변수가 생성됩니다.

그건 그렇고, 대신에:

shift arr

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

shift 1 arr

또는:

arr[1]=()

이 코드는 배열 변수로 선언되었는지 여부 에 따라 의미( vs ) shift arr가 다르기 때문에 모호합니다 . 전자를 사용하면 원하는 것이 무엇인지 더욱 분명해집니다.shift 1 arrshift arr argvarrshift 1 arr

답변2

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

관련 정보