(...)에 설정된 변수가 bash에서 손실되는 이유는 무엇입니까? [복사]

(...)에 설정된 변수가 bash에서 손실되는 이유는 무엇입니까? [복사]
$ p="pineapple" ; echo $p
pineapple
$ (p="peach" ; echo $p)
peach
$ echo $p
pineapple

쉘이 마지막으로 초기화된 이후 왜 복숭아를 표시하지 않습니까? 괄호가 이 결과에 영향을 미치나요?

답변1

예, 이것이 바로 Bourne 및 csh와 같은 쉘에서 괄호가 수행하는 작업입니다. bash수정이 제한되는 서브쉘 환경(하위 프로세스 분기를 포함하여 대부분의 쉘에서)을 도입합니다.

변수, 옵션, 별칭, 함수, 리디렉션, 현재 작업 디렉터리, 신호 구성 등 해당 하위 쉘 환경 내의 쉘 상태에 대한 모든 변경 사항은 종료 시 손실(복원)됩니다.

실행하는데 매우 유용함오직다른 환경의 일부 명령.

예를 들어:

(cd /some/dir && cmd)

cmd다른 디렉터리에서 실행하세요.

아니면 다음과 같습니다:

(IFS=:; set -o noglob; ls -l -- $PATH)

우리는 하나의 확장에 대해서만 Split+Glob 연산자를 조정합니다 $PATH.

하위 쉘 환경을 도입하지 않고 명령을 그룹화하려면 {}키워드를 사용하십시오.

a=1
{ echo "I'm running in the main shell environemnt"; a=2;}
echo "$a"
(echo "I'm running in a subshell environment"; a=3)
echo "$a"

{;a 앞뒤의 공백 은 }일반 문자로 구성된 키워드이고 (및 는 )여기서 서브쉘 구성에 사용되는 쉘 구문의 특수 문자이기 때문입니다 (...).

또한 이것이 (...)서브쉘 환경을 도입하는 유일한 구성이 아니라는 점에 유의하십시오. 또한 (Bourne/Korn 유사 쉘에서):

  • 어떤 형태의 명령 대체: $(subshell)또는`subshell`
  • 프로세스 대체: <(subshell), >(subshell),=(subshell)
  • 파이프라인 구성 요소: ( { subshell; } | othercommandAT&T ksh 또는 zsh의 마지막 구성 요소가 아님)
  • 비동기 명령:{ subshell; } &
  • 공동 처리: { subshell; } |&또는coproc { subshell; }

POSIX 쉘 구문에서는 및 { ...; }둘 다 (...)호출됩니다.복합 명령. 둘 다 기능에 할당할 수 있습니다. 함수를 다음과 같이 정의합니다.

func() (
  ...
)

바꾸다

func() {
  ...
}

즉, 함수의 본문은 일단 호출되면 서브셸 환경에서 실행되므로 스크립트처럼 동작합니다(호출자로부터 모든 변수, 별칭, 함수, 옵션 등을 계속 상속한다는 점만 제외).

fish껍질 에서는 (...)완전히 다른 것입니다. 이는 명령 대체이지만아니요서브셸 환경을 도입합니다.

fish> set a 1; echo $a (set a 2; echo $a) $a
1 2 2

ksh93 또는 mksh 쉘의 명령 대체 형식 과 유사하며 ${ ...; }하위 쉘 환경을 도입하지 않습니다.

관련 정보