2011-09-26 3 views
2

원래 텍스트는 below.It 그림의 프로그램이 4.24 특정 디렉토리를 변경 한 후 getcwd를 호출이 작업 디렉토리를 인쇄하는 4.22(UNIX에서 심볼릭 링크에 대한) APUE2에서의 혼란

섹션에서입니다 . 우리가 프로그램을 실행하면, 우리는 우리가 그것을 예상대로 CHDIR이 나누었다는 디렉토리 트리를가는 경우가 안타 때에 getcwd 아무 생각이 없습니다/그림 4.17에서 심볼릭 링크를 따라하는 것이

$ ./a.out 
cwd = /var/spool/uucppublic 
$ ls -l /usr/spool 
lrwxrwxrwx 1 root 12 Jan 31 07:57 /usr/spool -> ../var/spool 

주를 얻을 수 var/spool 디렉토리 (기호 링크/usr/spool이 가리키는). 이것은 기호 링크의 특성입니다.

저자가 실제로 프로그램이 /var/spool에 도달했다고 말하면서 무엇을 의미합니까? 저자가 지적한 기호 연결의 특성은 무엇입니까? 나는 정말로 이해하지 못했다.

답변

2

참고 일부 있음 쉘 (특히 bash)은 심볼릭 링크를 추적하여 주어진 디렉토리에 도착했는지 여부를 추적하고 이에 따라 현재 디렉토리를 인쇄합니다. 적어도 bash는 물리적 또는 논리적 디렉토리 변경을 할 cd에 옵션이 있습니다

cd [-L|-P] [dir]

변경 디렉토리에 현재 디렉토리를. HOME 변수가 기본 디렉토리입니다. [...]-P 옵션은 기호 링크를 따르는 대신 실제 디렉토리 구조를 사용합니다 (세트 내장 명령에 대한 -P 옵션 참조). -L 옵션을 사용하면 기호 링크를 따라야합니다. 인수가 -이면 $ OLDPWD와 같습니다. CDPATH의 비어 있지 않은 디렉토리 이름이 사용되거나 -이 첫 번째 인수이고 디렉토리 변경이 성공하면 새 작업 디렉토리의 절대 경로 이름이 표준 출력에 기록됩니다. 디렉토리가 성공적으로 변경되면 리턴 값은 true입니다. 그렇지 않으면 false. /usr/spool 다음 /var/spool에 대한 심볼릭 링크입니다 표시된 시나리오에서

:

$ pwd 
/
$ cd /usr/spool/uucppublic 
/usr/spool/uucppublic 
$ cd -L .. 
/usr/spool 
$ cd /usr/spool/uucppublic 
/usr/spool/uucppublic 
$ cd -P .. 
/var/spool 
$ 

대부분의 사람들은, 일반 cd ..cd -L ..과 동일 할 것입니다. 원하는 경우 bashcd -P ..과 동일하게 (set -P 또는 set -L을 사용하여) 선택할 수 있습니다.

현재 디렉토리의 경로 이름을 찾는 프로세스도 이해해야합니다. 논리적으로 프로세스 (커널)는 현재 디렉토리 (.)를 열고 inode 번호 (및 장치 번호)를 읽습니다. 그런 다음 상위 디렉토리 (..)를 열고 일치하는 inode 번호 (및 장치 번호)가있는 항목을 찾을 때까지 항목을 읽습니다. 그런 다음 경로 이름의 마지막 구성 요소를 제공합니다. 루트 디렉토리 (여기서 ...에 대한 inode 번호가 같고, 다음 디렉토리의 디렉토리 번호가 같을 때까지 다음 디렉토리의 inode 번호를 찾고 부모 디렉토리 (../..) 등을 열어 프로세스를 반복 할 수 있습니다. 값은 통상적으로 2)이다. 이것은 심지어 마운트 지점에서 작동합니다. 자동 마운트 된 원격 (NFS) 파일 시스템을 조심하십시오. 위의 순진한 검색 개요가 올바른 기계를 찾을 때까지 모든 기계를 마운트하기 때문에 수백 개의 자동 마운트 된 기계가있는 디렉토리를 통해 스캔하면 실제로 느려질 수 있습니다. 따라서 실제 getcwd() 함수는 이보다 더 명확하지만 현재 디렉토리의 경로를 찾는 방법을 설명합니다. 또한 /var/spool/uucppublic 아래의 디렉토리를 평가할 때 프로세스가 /usr/spool을 발생시키지 않는 이유를 보여줍니다. /usr 디렉토리를 열지 않습니다.

realpath() 함수 (시스템 호출)는 아마도 심볼릭 링크를 참조하는 이름을 취하고 심볼릭 링크를 전혀 포함하지 않는 이름으로 해석합니다. /usr/spool/uucppublic을 전달하면 예를 들어 /var/spool/uucppublic을 반환합니다.

+0

+1 : 저는 bash의 (IMO 이상한) 행동을 알지 못했습니다. –

+0

@Jonathan Leffler 우수 작품! bash의 동작을 어떻게 알 수 있습니까? –

2

/var/spool을 가리키는 기호 링크 /usr/spool이 있다고 가정합니다.

기호 링크 (예 : cd /usr/spool)를 따르면 길 찾기 디렉토리 (/var/spool)가됩니다. 그런 다음, 심볼릭 링크를 따라 간 정보가 손실됩니다. cd /var/spool을 (를) 직접 했는데도 /var/spool에 있습니다.

추가 cd ..은 과 대조적으로 /var입니다.

UPDATE :

로 키이스 톰슨과 요나단 레플러에 의해 지적, 당신이 다음에 경로 (즉 /usr/spool)를 기억하십니까 일부 포탄이있다. 그러한 쉘에서 cd ../usr/으로 갈 것입니다. 그러나 그러한 쉘에서 시작된 프로그램은 여전히 ​​작업 디렉토리로 /var/spool을 볼 수 있습니다.

아마도 이것은 저자가 cwd을 표시하기위한 프로그램을 작성하게 한 이유 일 것입니다 (그러한 쉘의 내부를 해결하려면).

+0

질문이 있습니다.내가 심볼릭 링크를 잃어 버렸을 때, 프로그램이 어떻게 작성자가 지적한/var/spool에 충돌 할 수 있습니까? –

+0

'cd /'/ usr/spool '명령을 실행하면 시스템은 심볼릭 링크를 해결합니다 (그 시점에서 그것은 심볼릭 링크에 대해 알고있다.) 그리고 나서'/ var/spool'로 간다. 그 다음에는/usr/symlink에 처음 액세스했을 때 그곳에 "더 이상"알지 못한다. –

2

@undor_gongor 쓴 것에 확장 :

각 프로세스는 현재 작업 디렉토리가 있습니다. 디렉토리의 경로 이름으로 저장되지 않습니다. 디렉토리 자체에 대한 참조입니다.

경로 이름으로 저장 한 경우 getcwd() 기능의 작업은 간단합니다. 경로 이름 만 인쇄하십시오. 대신 현재 디렉토리를 읽고, 그 디렉토리의 .. 항목을 연 다음 그 디렉토리의 .. 항목을 열어 루트 (즉, .. 항목이 디렉토리 자체를 가리키는 디렉토리)에 도달 할 때까지 계속해야합니다. 현재 디렉터리의 전체 경로를 역순으로 빌드합니다.

..은 기호 링크가 될 수 없기 때문에이 프로세스는 기호 링크의 영향을받지 않습니다.

(쉘은 $PWD 또는 $CWD 변수가있을 수 있습니다, 또는 pwd 내장, 그는 심볼릭 링크에 의해 영향을받는, 이러한 일반적 cd 또는 pushd에 전달 된 문자열을 기억하여 작동합니다.)

+0

+1 : 내 것보다 훨씬 나은 대답. –

관련 문제