Symlink 폴더 안에 있을 때 상위 위치에서 파일을 복사합니다.

Symlink 폴더 안에 있을 때 상위 위치에서 파일을 복사합니다.

/tmpparentCalled 및 에 두 개의 폴더를 생성한다고 가정해 보겠습니다 child. child라는 파일이 포함되어 test-child.txt있으며 parent이라는 파일이 포함되어 있습니다 test-parent.txt. 이제 들어가서 parent에 대한 심볼릭 링크를 만들어 보겠습니다 child. 다음으로 들어가서 에서 복사해 child보세요 . Bash 완료는 잘 작동하지만 실제 파일 복사는 실패합니다.test-parent.txtparent

cd /tmp
pwd
/tmp
mkdir parent
mkdir child
touch child/test-child.txt
ls child/
test-child.txt
cd parent
ln -sf ../child .
touch test-parent.txt
cd child
cp ../test-parent.txt .
cp: cannot stat ‘../test-parent.txt’: No such file or directory 

왜? ?

그리고 제가 거기 있는 동안 child제가 이렇게 말하면--

pwd
/tmp/parent/child

답변1

쉘은 사용자의 편의를 위해 기호 링크를 따릅니다. 이는 디렉토리에 대한 심볼릭 링크인 cd foo && cd ..경우에도 항상 원래 디렉토리로 돌아가는 좋은 효과가 있습니다 . foo여기에는 두 가지 단점이 있습니다. 가장 큰 단점은 다른 프로그램에서는 이 기능을 수행하지 않는다는 것입니다. 또한 기호 디렉터리 추적에는 자체적인 문제가 발생합니다(기호 링크가 변경되면 어떻게 됩니까? 프로세스에 기호 링크를 읽을 수 있는 권한이 없으면 어떻게 됩니까? 등).

쉘은 모든 디렉토리 변경 사항을 추적하여 거기에 어떻게 도달했는지 기억하기 때문에 이 작업만 수행할 수 있습니다. 새 프로세스가 시작되면 이 기록 정보를 얻지 못합니다. 뒤에서는 루트 디렉터리에 도달할 때까지 링크를 따라 현재 디렉터리에서 위로 이동하여 ..위치를 찾습니다 .

심볼릭 링크를 통해 디렉토리에 도달하는 경우 다음 명령을 사용하여 심볼릭되지 않은 링크의 경로를 인쇄할 수 있습니다.pwd내장형, pwd -P셸에서 다른 프로그램을 호출하는 경우 ..기호 링크 구성 요소가 포함된 경로를 전달하지 마십시오. 프로그램이 이를 다르게 해석하기 때문입니다. 대신 다음을 ..호출하여 구성 요소를 제거하십시오 pwd -P.

cp "$(cd .. && pwd -P && echo /)test-parent.txt" .

cd쉘 세션에서 이전 명령에 사용된 심볼릭 링크를 잊으려면 다음을 실행하십시오.

cd "$(pwd -P && echo /.)"

이는 현재 디렉토리로 변경되므로 쉘 프로세스의 현재 디렉토리를 효과적으로 변경하지는 않지만 쉘이 추적하는 현재 디렉토리의 경로를 변경하여 심볼릭 링크되지 않은 링크로 만듭니다.

1이것이 전통적으로 통화가 작동하는 방식 입니다 getcwd. 일부 커널은 현재 디렉토리를 추적하지만 이전 버전과의 호환성을 위한 이유가 아닌 경우(심볼릭 링크의 미묘한 경우도 있기 때문에) 심볼릭 링크는 추적하지 않습니다.

답변2

cp이는 쉘이 동일한 링크 게임을 수행하지 않기 때문입니다 . 귀하의 쉘은 현재 작업 디렉토리의 간접 참조로 현재 작업 디렉토리에 대한 링크를 따르고 있지만 쉘이 호출되면 커널은 말도 안되는 것을 원하지 않습니다. 대신 커널은 현재 작업 디렉토리에 대한 완전한 절대 경로를 cp생성합니다 cp작업 디렉토리 - 그래서 링크는 .쉘의 링크와 .다릅니다 ..

현재 작업 디렉터리의 절대 경로를 쉽게 확인할 수 cd -P .있으며 다른 디렉터리에도 동일하게 적용됩니다 cd -P -- /any/other/directory.적어도와 같은 인쇄를 위한 절대 경로 pwd이며, 많은 쉘에서는 절대 경로로 변경되기도 합니다..pwd -P$PWD(같은 방법으로 cd -P .).

예를 들어:

cd /tmp
mkdir -p parent child
cd parent
ln -s ../child child
touch ./child/somefile
cd -L child                  ###the default
printf %s\\n "$PWD"/*
cd -P .
printf %s\\n "$PWD"/*

산출

/tmp/parent/child/somefile
/tmp/child/somefile

관련 정보