popd의 쉘 확장이 스택에서 디렉토리를 제거하지 않는 이유는 무엇입니까?

popd의 쉘 확장이 스택에서 디렉토리를 제거하지 않는 이유는 무엇입니까?

단독으로 사용 하면 popd스택에서 디렉터리를 제거하고 해당 디렉터리로 이동합니다. 그러나 이렇게 하면 cd $(popd)스택에서 디렉터리가 제거되지 않습니다.

프로세스가 포크되고 결과가 쉘 확장 위치에 배치되므로 스택에서 디렉토리를 제거하는 것은 어떨까요?

답변1

구문은 $(...)"쉘 확장"이 아니라 "명령 대체"입니다.

이 구문을 사용하면 하위 쉘이 생성되고 그 안에 있는 명령이 실행되며 표준 출력이 명령줄에 반환됩니다. 예를 들어,

x=$(cd /tmp ; ls)

명령은 하위 쉘에서 실행됩니다 cd. 이는 기본 프로세스의 현재 디렉토리가 변경되지 않음을 의미합니다.

비슷한 방식으로 하위 프로세스에서 실행 cd $(popd)되므로 popd하위 프로세스만 영향을 받으며 상위 프로세스는 영향을 받지 않습니다.

이 간단한 테스트를 통해 하위 프로세스에 영향을 미쳤음을 확인할 수 있습니다.

$ pushd /tmp
/tmp ~
$ pushd /
/ /tmp ~
$ dirs
/ /tmp ~
$ cd $(popd ; dirs >&2)
/tmp ~
$ dirs
/tmp /tmp ~

dirs >&2쉘 내부의 $(...)디렉토리 스택이 팝되었음을 나타냅니다 .어린이프로세스의 상위 스택은 영향을 받지 않습니다.

답변2

명령 대체는 $(…)서브셸에서 명령을 실행합니다. 서브쉘은 메인 쉘의 동일한 복사본으로 시작하지만 그 시점부터 메인 쉘과 서브쉘은 각자의 삶을 살아갑니다.

  1. 쉘 프로세스는 파이프와 포크를 생성합니다.
  2. 하위 프로세스는 popd해당 출력이 파이프에 연결된 동안 실행된 다음 종료됩니다.
  3. 부모는 파이프에서 데이터를 읽고 이를 명령줄로 바꿉니다.

자식 프로세스에서 실행되기 때문에 popd그 효과는 자식 프로세스로 제한됩니다. 목차스택에서 제거 — 하위 스택에서 제거합니다. 상위 스택에는 변경 사항이 없습니다.

1은 거의 동일합니다. 이러한 차이점은 여기서는 관련이 없습니다.

답변3

pushd다른 환경 변수와 마찬가지로 하위 쉘에서는 변경되지만 상위 쉘에서는 변경되지 않은 상태로 popd유지되는 변수에 스택을 유지합니다 .DIRSTACK

추가 읽기.

관련 정보