현재 디렉토리를 삭제할 때의 bash 동작

현재 디렉토리를 삭제할 때의 bash 동작

을 사용하고 있습니다 GNU bash, version 4.3.42(1)-release (x86_64-redhat-linux-gnu).

가상 디렉터리를 만들고 hello그곳으로 이동했습니다. 안으로 들어가면 /tmp/hello디렉토리 자체를 삭제했습니다.

$ pwd
/tmp/hello
$ rmdir $PWD

확인했는데 여전히 해당 디렉토리에 있습니다.

$ pwd
/tmp/hello

그런 다음 디렉터리 자체로 이동하려고 시도했지만 물론 불가능했습니다(이미 디렉터리에 있었음에도 불구하고).

$ cd $PWD
bash: cd: /tmp/hello: No such file or directory

그런데 .cd .cd $PWD이것은 어떻게든 작동합니다.

$ cd .
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory

놀랍게도 나는 이제 새로운 "사물"에 빠져 있습니다.

$ pwd
/tmp/hello/.

물론 이전 디렉터리로 이동하려고 하면 실패합니다.

$ cd -
bash: cd: /tmp/hello: No such file or directory

흥미롭게 man도 단 한 페이지도 작동하지 않습니다.

$ man cd
man: can't change directory to '': No such file or directory
man: command exited with status 255: (cd  && LESS=-ix8RmPm Manual page cd(1) ?ltline %lt?L/%L.:byte %bB?s/%s..?e (END):?pB %pB\%.. (press h for help or q to quit)$PM Manual page cd(1) ?ltline %lt?L/%L.:byte %bB?s/%s..?e (END):?pB %pB\%.. (press h for help or q to quit)$ MAN_PN=cd(1) less -s)

왜 이런 일이 발생합니까?

답변1

@BinaryZebra에 동의합니다. 이 질문은 이전에 요청된 적이 있음을 지적하는 것이 공정합니다(예:명령줄 인터페이스를 사용하여 내부에서 디렉터리 삭제[복사], 참조할 수 있습니다.무기한), 관찰 가능한 특성은 잘 알려져 있습니다.

POSIX 관련 동작에 대한 설명은 POSIX 관련 동작에 대한 정보를 제공할 수 있기 때문에 더 흥미롭습니다.예상되는행동. 관련 POSIX 문서는 다음과 같습니다.

내부에애플리케이션 사용법CD 부분은 주목할 가치가 있습니다.

cd는 현재 쉘 실행 환경에 영향을 주기 때문에 항상 일반 쉘 내장 명령으로 사용할 수 있습니다.

내부에설명하다섹션 CD의 항목 10은 가장 관련성이 높은 정보를 제공합니다.

  1. 그런 다음 cd 유틸리티는 다음과 동일한 작업을 실행해야 합니다.chdir()통화 기능코파스경로 매개변수로. 어떤 이유로든 이러한 작업이 실패하면 cd유틸리티는 해당 오류 메시지를 표시하고 이 단계의 나머지 부분을 수행하지 않습니다. 이 -P옵션이 유효하지 않은 경우 PWD9단계 진입 시(즉, 상대 경로 이름으로 변환하기 전) 환경 변수를 curpath 값으로 설정해야 합니다. 이 -P옵션이 적용되는 경우 PWD환경 변수는 출력될 문자열로 설정되어야 합니다 pwd -P. 새 디렉터리 또는 이 디렉터리의 상위 디렉터리에 현재 작업 디렉터리를 결정할 수 있는 충분한 권한이 없으면 PWD환경 변수 값이 지정되지 않습니다.

즉, PWD그것은산출명령 cd보다는입력하다, 그래서 대체로무시당하다명령 으로 cd. "지정되지 않음"에 대한 마지막 설명을 참고하세요. POSIX는 $PWD호출이 실패하면 chdir()어떻게 되는지 밝히기를 거부했습니다 .

토론 중환경 변수의 경우 pwdPOSIX 주석은 다음과 같습니다 PWD.

현재 작업 디렉터리의 절대 경로 이름입니다. 애플리케이션이 값을 설정하거나 설정 해제하면 PWD동작이 pwd지정되지 않습니다.

즉, POSIX는 명령을 성공적으로 사용하는 것(성공적인 호출과 일치 ) $PWD이외의 명령을 설정할 수 있는 다른 방법을 지정하는 것을 거부합니다.cdchdir()

두 문서 모두 경로가 "캐시됨"을 의미하는 것으로 해석될 수 있는 문구가 없으며 단순히 작업 디렉터리가 존재한다는 의미입니다(아마도)내부에쉘 실행 환경. 토론 자체에서는 cd디렉토리가 이름 없이 계속 존재할 가능성에 대해 언급하지 않습니다. 문서 자체도 cd존재하지 않는 디렉토리에 대해서는 신경 쓰지 않습니다. 이는 설명에서 수행됩니다.chdir()기능은 실패의 여러 원인 중 하나입니다. 예를 들어

[ENOENT]
~의 일부기존 디렉토리의 이름을 지정하지 마십시오.빈 문자열입니다.

설명에는 chdir()특별한 처리에 대한 언급이 없습니다. "."아마도 POSIX가 다음을 사용하여 절대 경로 이름을 계산하는 프로세스를 자세히 설명하지 않기 때문일 것입니다.getcwd()예를 들어 "."및 가 없는 파일 시스템을 허용합니다 "..". 이것이 실제로 사실이라면 누군가 구현이 작동 chdir(".")하지 않는 것으로 간주될 수 있음을 지적하기 위해 문구를 추가할 수 있습니다.

10단계로 돌아가면 다음과 같이 명확하게 설명됩니다.

어떤 이유로든 이러한 작업이 실패하면 cd 유틸리티는 적절한 오류 메시지를 표시하고 이 단계의 나머지 부분을 수행하지 않습니다.

업데이트 PWD완료뒤쪽에그 문장이니까 바꿀 가능성은 없지그것은실패시 값.

뒤로 , 이 옵션 pwd에 대해 이야기합니다.-L

PWD환경 변수가 현재 디렉토리에 대한 절대 경로 이름을 포함하고 파일 이름 점 또는 점-점을 포함하지 않는 경우 , pwd이 경로 이름은 표준 출력에 기록되어야 합니다.

그 다음에

둘 다 지정되지 않은 경우 -L유틸리티 는 지정된 것처럼 작동 -P합니다 .pwd-L

따라서 일련의 가정된 동작이 있지만 쉘에 대한 명시적인 설명은 없습니다.사용변수 PWD자체는 작업 디렉터리의 컨테이너 역할을 합니다. 대신 다음은 다음과 같습니다.명시되지 않은이를 통해 일부 POSIX 호환 애플리케이션은 "가상 동작" 지점을 충족하는 한 데이터를 구성하는 다른 방법을 선택할 수 있습니다.

답변2

POSIX 문서 설명에 대한 개인적인 해석을 반복하는 것은 OP에 도움이 되지 않습니다. POSIX를 자세히 설명하는 몇 가지 다른 질문이 있습니다. 그런데 이 질문.


몇 가지 기본 설명:
. Linux/Unix의 잘 알려진 특징은 사용 중에 파일(디렉토리)이 삭제될 수 있다는 것입니다. 그렇기 때문에 영화를 삭제한 후에도 계속 시청할 수 있습니다. 파일은 디렉토리 항목의 inode가 삭제될 때만 실제로 사라집니다.

두번째. 환경 변수 $PWD의 값이 변경되더라도 쉘은 실제 pwd의 내부 값을 유지합니다.

@yaegashi가 수락한 답변에 대한 첫 번째 댓글은 어디를 봐야 하는지 보여줍니다( pwd 소스).

내가 옳다. 바라보다유래pwd_builtin(). 단지 the_current_working_directory의 내용을 인쇄합니다. – 야에가시 7월 31일 16:01

표시된 대로 PWD에 홀수 값으로 시작하더라도 쉘은 여전히 ​​pwd("/home/user")에 대한 올바른 값을 알고 있습니다.

. 일부 특수한 경우에는 셸에 저장된 값이 실제와 동기화되지 않을 수 있다는 점을 쉽게 이해할 수 있습니다.

삭제된 디렉터리에서 작업하는 것은 cd .이러한 특수 사례 중 하나인 것 같습니다. 쉘은 실패 시 마지막으로 알려진 비밀번호에 점을 추가하는 것 같습니다.


너의 문제:

1. PWD 디렉토리를 삭제하고 내장 pwd를 실행하십시오.

$ pwd
/tmp/hello
$ rmdir $PWD;   pwd
/tmp/hello

pwd 내장 기능은 쉘이 메모리에 보관하는 pwd 값을 보고합니다. 실패는
외부적 으로 보고됩니다 /bin/pwd.
흥미롭게도 보고 pwd -P(Bash의 내장 기능도 포함)는 실패를 보고합니다.

$ pwd -P
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory

또한 pwd -P내장 명령을 사용한 후에는 일반 pwd가 실패합니다. 메모리의 pwd 값이 업데이트되었기 때문이라고 생각합니다.

2.CD $PWD

그런 다음 디렉터리 자체로 이동하려고 시도했지만 물론 불가능했습니다(이미 디렉터리에 있었음에도 불구하고).

   $ cd $PWD
   bash: cd: /tmp/hello: No such file or directory

디렉토리를 읽을 수 없으면(디렉토리가 존재하지 않는 경우) 디렉토리 경로를 따르려는 실제 시도는 실패합니다.

삼.CD.

cd .하지만 동일해야 하기 때문에 cd $PWD를 사용해 보았습니다 . 이것은 어떻게든 작동합니다.

   $ cd .
   cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory

쉘은 알고 있는 pwd 경로에 액세스하려고 시도하지만 실패합니다. 쉘이 보고하는 내용은 다음과 같습니다. FAILED! 여기에는 문제가 없습니다.

4.새로운 길.

놀랍게도 나는 이제 새로운 "사물"에 빠져 있습니다.

$ pwd
/tmp/hello/.

PWD 메모리의 값이 실제 상황과 일치하지 않아 점(.)이 추가됩니다. 재사용하면 cd .포인트가 추가되기 때문입니다.

$ cd .; pwd
/tmp/hello/./.

그리고 예기치 않게 a 는 cd ..pwd 및 $PWD 만 생성합니다 ...

$ cd ..; pwd; echo $PWD
..
..
$ cd ..; pwd; echo $PWD
../..
../..

5.전 장애인.

물론 이전 디렉터리로 이동하려고 하면 실패합니다.

$ cd -
bash: cd: /tmp/hello: No such file or directory

이는 PWD의 이전 값(OLDPWD의 bash에 저장됨)을 존중할 수 없기 때문에 발생합니다.
이것은 (위에서 보고한 대로) /tmp/hello/.(hello로 제거됨) 따라갈 수 없으며 성공하거나 cd -실패 cd $OLDPWD합니다.

$ echo $OLDPWD                 # at this point following your exact procedure.
/tmp/hello/.

6.매뉴얼 페이지

흥미롭게도 매뉴얼 페이지도 작동하지 않습니다.

이 시점에서 매뉴얼 페이지는 사실 모든 면에서 나에게 잘 작동합니다.

답변3

POSIX현재 디렉터리 경로가 캐시되어야 하고, 삭제된 디렉터리가 여전히 존재하지만 이름이 없어야 합니다.

cd .분명히 해당 문자열을 현재 캐시된 이름에 추가하는 것 같습니다.

관련 정보