다른 답변은 지나치게 단순화 된 것인데, 각각은 이야기의 일부만 제시하며 몇 가지 점에서 잘못되었습니다.
작업 디렉토리를 추적하는 두 가지 방법 이 있습니다 .
- 모든 프로세스에 대해 해당 프로세스를 나타내는 커널 공간 데이터 구조에서 커널은 작업 디렉토리의 vnode와 해당 프로세스의 루트 디렉토리에 대한 두 개의 vnode 참조를 저장합니다. 전자 참조는
chdir()
및 fchdir()
시스템 호출에 의해 설정되고 후자는에 의해 설정됩니다 chroot()
. /proc
Linux 운영 체제에서 또는 fstat
FreeBSD 의 명령 등을 통해 간접적으로 볼 수 있습니다 .% fstat -p $$ | 헤드 -n 5
사용자 CMD PID FD 마운트 숫자 모드 SZ | DV R / W
JdeBP ZSH 92648 텍스트 / 24958 -R-XR-XR-X 702360R
JdeBP zsh 92648 ctty / dev 148 crw--w ---- pts / 4 rw
JdeBP ZSH 92648 WD / usr / home / JdeBP 4 drwxr-xr-x 124 r
JdeBP ZSH 92648 루트 / 4 drwxr-xr-x 35 r
%
경로 이름 분석이 작동하면 경로가 상대인지 또는 절대인지에 따라 참조 된 vnode 중 하나에서 시작됩니다. ( …at()
열린 (디렉토리) 파일 디스크립터가 세 번째 옵션으로 참조하는 vnode에서 경로 이름 분석을 시작할 수 있는 시스템 호출 제품군이 있습니다.)
마이크로 커널 Unices에서 데이터 구조는 응용 프로그램 공간에 있지만 이러한 디렉토리에 대한 열린 참조를 유지하는 원리는 동일하게 유지됩니다.
- 내부적으로, 예를 들면 Z, 콘, Bourne의 다시, C 및 Almquist 쉘로 쉘 내에, 쉘 부가 내부 변수 문자열의 문자열 처리를하여 작업 디렉토리 추적. 호출 할 때마다이 작업을 수행합니다
chdir()
.상대 경로 이름으로 변경되면 해당 이름을 추가하기 위해 문자열을 조작합니다. 절대 경로 이름으로 변경되면 문자열이 새 이름으로 바뀝니다. 두 경우 모두 제거 할 문자열 .
과 ..
구성 요소 를 조정하고 링크 된 이름으로 대체하는 심볼릭 링크를 추적합니다. ( 예를 들어 Z 쉘의 코드는 다음과 같습니다 .)
내부 문자열 변수의 이름은 추적되는 쉘 변수 의 이름 PWD
(또는 cwd
은 C 껍질). 이것은 일반적으로 환경 변수 ( PWD
)를 쉘이 생성 한 프로그램에 내 보냅니다.
추적 일들이 두 가지 방법이 계시되어 -P
및 -L
받는 옵션 cd
과 pwd
쉘 내장 명령 및 내장 쉘 '의 차이에 의해 pwd
명령과 모두 /bin/pwd
명령 및 내장 pwd
같은 것들의 명령 (다른 사람의 사이에) VIM과 NeoVIM.
% mkdir a; ln -sab
% (cd b; pwd; / bin / pwd; printenv PWD)
/ usr / home / JdeBP / b
/ usr / home / JdeBP / a
/ usr / home / JdeBP / b
% (cd b; pwd -P; / bin / pwd -P)
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
% (cd b; pwd -L; / bin / pwd -L)
/ usr / home / JdeBP / b
/ usr / home / JdeBP / b
% (cd -P b; pwd; / bin / pwd; printenv PWD)
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
% (cd b; PWD = / hello // bin / pwd -L)
/ usr / home / JdeBP / a
%
보다시피, "논리적"작업 디렉토리를 얻는 것은 PWD
쉘 변수 (또는 쉘 프로그램이 아닌 경우 환경 변수) 를 조사하는 문제입니다 . "실제"작업 디렉토리를 얻는 것은 getcwd()
라이브러리 함수 를 호출하는 문제입니다 .
옵션이 사용될 /bin/pwd
때 프로그램 의 작동 -L
은 다소 미묘합니다. 그것은 믿을 수 의 값 PWD
이 상속 한 것으로 환경 변수를. 결국, 그것은 쉘에 의해 호출 될 필요가 없으며 개재 프로그램은 PWD
환경 변수가 항상 작업 디렉토리의 이름을 추적 하게하는 쉘의 메커니즘을 구현하지 않았을 수도 있습니다 . 아니면 누군가 내가 방금했던 일을 할 수도 있습니다.
POSIX 표준에 따르면 시스템 호출 추적에서 볼 수 있듯이 주어진 이름이 name PWD
과 동일한 것을 생성 하는지 확인하십시오 .
.
% ln -sac
% (cd b; 트러스 / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ( "/ usr / home / JdeBP / b", { mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
stat ( ".", {mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
/ usr / home / JdeBP / b
% (cd b; PWD = / usr / local / etc 트러스 / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ( "/ usr / local / etc" , {mode = drwxr-xr-x, inode = 14835, size = 158, blksize = 10240}) = 0 (0x0)
stat ( ".", {mode = drwxr-xr-x, inode = 120932, size = 2 , blksize = 131072}) = 0 (0x0)
__getcwd ( "/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ usr / home / JdeBP / a
% (cd b; PWD = / hello / 트러스 / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ( "/ hello / there", 0x7fffffffe730) ERR # 2 '해당 파일이나 디렉토리가 없습니다'
__getcwd ( "/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ usr / home / JdeBP / a
% (cd b; PWD = / usr / home / JdeBP / c truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ( "/ usr / home / JdeBP / c ", {mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
stat (". ", {mode = drwxr-xr-x, inode = 120932 , 크기 = 2, blksize = 131072}) = 0 (0x0)
/ usr / home / JdeBP / c
%
보시다시피 : getcwd()
불일치를 감지 한 경우 에만 호출 합니다. PWD
실제로 동일한 디렉토리의 이름을 지정하지만 다른 경로로 문자열을 설정 하여 속일 수 있습니다 .
getcwd()
라이브러리 함수는 고유의 권리로 될 수 있습니다. 그러나 précis :
탐색 ..
은 다시 그 자체로 주제입니다. 또 다른 PRECIS : (이미이가되어 언급,이기는하지만 종래 디렉토리 만 하지 실제를 포함 필수) ..
디스크의 디렉토리 데이터 구조는, 커널은 각 디렉토리의 vnode에 자신의 부모 디렉토리를 추적하고 있습니다 따라서 탐색 ..
어떤의 vnode에 작업 디렉토리. 이 대답의 범위를 벗어난 마운트 지점과 변경된 루트 메커니즘으로 인해 다소 복잡합니다.
곁에
실제로 Windows NT도 비슷한 일을합니다. 프로세스 당 단일 작업 디렉토리가 있으며 SetCurrentDirectory()
API 호출에 의해 설정되고 해당 디렉토리에 대한 (내부) 열린 파일 핸들을 통해 커널이 프로세스별로 추적합니다. Win32 프로그램 (명령 해석기뿐만 아니라 모든 Win32 프로그램)이 디렉토리를 변경할 때마다 추가하거나 덮어 쓰는 여러 작업 디렉토리 (드라이브 당 하나)의 이름을 추적하는 데 사용하는 환경 변수 세트가 있습니다 .
일반적으로 Unix 및 Linux 운영 체제의 경우와 달리 Win32 프로그램은 이러한 환경 변수를 사용자에게 표시하지 않습니다. 그러나 Windows NT에서 실행되는 Unix와 유사한 서브 시스템 SET
에서 특정 방식으로 명령 인터프리터의 명령 을 사용하여이를 볼 수 있습니다.
추가 자료