디렉터리 및 상대 경로에 대한 기호 링크

디렉터리 및 상대 경로에 대한 기호 링크

디렉터리에 대한 절대 경로를 사용하여 기호 링크(Blink)를 만들었고 다음 예제 트리가 있습니다.

$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr  3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr  3 12:27 foo

$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr  3 12:27 bar

그런 다음 /tmp/A로 이동하여 디렉토리를 Blink로 변경합니다.

$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink

cd ..반환 /tmp/A 하지만 예를 들어 입력하면 ls ../foo오류가 발생합니다.

ls: ../foo: No such file or directory

내장된 cd 명령은 필요에 따라 경로를 확인하지만 외부 ls는 ..을 /tmp/B 위에 있는 것으로 처리하므로 foo를 찾을 수 없습니다.

여기서 문제가 무엇입니까? 상대 경로(예: ../foo)를 통해 /tmp/A/Blink에서 foo 파일을 가져올 수 있나요?

답변1

쉘은 현재 작업 디렉토리를 에 저장합니다 $PWD. 이것이 쉘 내장 cd및 용도이며 pwd, 보시다시피 기호 링크를 일반 디렉토리로 처리합니다. 때로는 도움이 되기도 하고 그렇지 않을 때도 있습니다.

다음을 사용하여 실제 디렉터리를 찾을 수 있습니다 pwd( help pwd자세한 내용을 보려면 입력하세요).

$ pwd
/tmp/A/Blink
$ pwd -L
/tmp/A/Blink
$ pwd -P
/tmp/B

다시 말하지만, cd옵션이 있습니다 -P(다시 말하지만, help cd친구입니다).

$ cd /tmp/A/Blink
$ pwd
/tmp/A/Blink
$ cd -P ..
$ pwd -P
/tmp

마지막으로 "기능"을 완전히 끌 수 있습니다:

$ set -P
$ cd /tmp/A/Blink
$ pwd
/tmp/B

답변2

내 생각엔 당신이 그렇게 할 수 없을 것 같아요. 오늘날의 쉘은 현재 위치에 어떻게 도달했는지 추적하고 파일 시스템과 운영 체제에 의존하여 저장하는 대신 현재 작업 디렉토리를 이름별로 추적합니다. 이는 내장 프로그램이 cd".." 체인을 직접 따르기보다는 심볼릭 링크를 "백업"할 수 있음을 의미합니다.

그러나 이를 실행하면 ls ../fools이 심볼릭 링크를 통해 디렉토리에 도달했다는 사실을 알 수 없습니다. 작업은 "../foo" 에서 수행됩니다 ls. stat()".." 부분은 현재 디렉터리에서 나오며, 상위 디렉터리에는 ".." 항목이 하나만 있습니다. 전체 심볼릭 링크는 디렉토리에 단일 "."이 있는 방식을 변경하지 않습니다. 그리고 ".." 항목이 있습니다. 기호 링크를 사용하면 커널이 파일 경로에 추가 간접 계층을 삽입할 수 있습니다. "../whatever"를 open()or 에 전달하면 stat()커널은 단순히 호출 프로세스의 현재 작업 디렉터리를 사용하여 ".."로 명명된 디렉터리를 결정합니다.

답변3

Bruce와 ams는 그 뒤에 있는 행동을 설명하는 좋은 답변을 제공했습니다. 하지만 실제로 ls ../foo요청한 작업을 수행하려면 다음과 같은 것을 선택할 수 있습니다.

ls $(dirname $PWD)/foo

답변4

넌 할 수 없어 왜냐하면/tmp/A/Blink 실제로 /tmp/B. 그래서 ls ../A/foo작동합니다.

대신에, 당신은 당신이 할 수 있다는 것을 알 수 있습니다CD도착하다진짜 /tmp/B별칭이 아닌 디렉터리 /tmp/A/Blink이를 위해 다음 함수를 대신 사용할 수 있습니다 cd(.bashrc에 넣을 수 있습니다).

lcd() { cd $(readlink -f "$1"); }

lcd물론 일반 디렉토리와 심볼릭 링크 디렉토리에서 작동합니다.
참고: readlink -f링크의 최종 대상에 대해 작동합니다(링크가 데이지 체인으로 연결된 경우).

관련 정보