디렉토리를 가리키는 심볼릭 링크를 만드는 데 사용할 수있는 pot 등원 명령은 무엇입니까?


16

디렉토리에 대한 심볼릭 링크를 생성하는 쉘 스크립트에 명령을 넣고 싶지만이 스크립트는 계속 실행될 수 있으므로 후속 호출에서 명령은 아무것도 변경해서는 안됩니다.

디렉토리 구조는 다음과 같습니다.

% tree /tmp/test_symlink 
/tmp/test_symlink
├── foo
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

foo/디렉토리를 가리키는 스 니펫이라는 심볼릭 링크를 만들고 싶습니다 /tmp/test_symlink/repo/resources/snippets.
그래서 나는 달린다.

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'

원하는 결과를 제공합니다.

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
├── foo
   └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

5 개 디렉토리, 5 개 파일

그러나 명령을 다시 실행하면

% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets/snippets' -> '/tmp/test_symlink/repo/resources/snippets'

디렉토리에 대한 심볼릭 링크를 생성하고 심볼릭 링크가 존재하는 곳에서 심볼릭 링크를 실제 디렉토리에 넣습니다.

% tree /tmp/test_symlink                                                          
/tmp/test_symlink
├── foo
   └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
    └── resources
        └── snippets
            ├── php.snippets
            ├── sh.snippets
            ├── snippets -> /tmp/test_symlink/repo/resources/snippets
            ├── snippets.snippets
            ├── sql.snippets
            └── vim.snippets

왜 이런 일이 발생하고 후속 호출로 인해이 이상한 효과가 발생하지 않도록 명령을 수정하려면 어떻게해야합니까?

답변:


16

-T이 옵션을 사용해야합니다. ln항상 링크 이름을 원하는 링크 이름으로 취급하고 디렉토리로 취급하지 않도록 지시 합니다.

이 옵션을 사용하지 않으면 ln디렉토리로 존재하는 링크 이름을 지정하면 해당 디렉토리 내의 대상에 대한 새 링크가 작성됩니다.

-T(적어도, 그것은 POSIX에없는)은 GNU-주의이지만, 이미 사용하고 -v내가 그 문제가되지 상상 있도록 GNU-주의도이다.

또는 부모 디렉토리를 링크 이름으로 지정하면 링크가 항상 (재) 생성됩니다.

ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/

심볼릭 링크가 대상과 이름이 같기 때문에 작동합니다.


덕분에 gnu 옵션은 반드시 휴대 할 필요는 없지만 이식성이 필수가 아닌 경우에 실제로 유용 할 수 있습니다. 당신의 대답은 저에게 효과적입니다. 매뉴얼 페이지에서 -n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory. -T, --no-target-directory treat LINK_NAME as a normal file always심볼릭 링크를 항상 파일로 취급하는 것이 낫다고 생각합니까? 이 "특별한"옵션의 사용을 제한하는 것이 더 좋을 것이라고 생각 했습니까?
the_velour_fog

사용할 수 있다는 것을 알고 있다면 GNU 특정 옵션 (IMO)을 피할 이유가 없습니다. dem 등원 명령을 요청했습니다. dem 등원 -T을 만드는 방법 ln입니다. 링크를 삭제하고 다시 작성하거나 foo이미 알고있는 경우와 같이 원하는 경우 동일한 결과를 얻는 다른 방법 ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/이 있습니다 (실제로 더 나은 답변이 될 수 있습니다. 업데이트하겠습니다).
Stephen Kitt

1
멋진, 그래 내가 이전에 사용했던 if심볼릭 링크의 존재를 감지하고 심볼릭 링크가 존재하는 경우 명령을 건너 문을하지만, 스크립트를 사용하지 않는 것처럼, 내가 뭔가 멱등하지만 간단한 위해 가고 있었다 읽어 복잡하고 어려운 받고 결국 mkdir -p에는 테스트를 , 논리 없음, 그냥 좋은 ol 한 라이너 :)
the_velour_fog

@Stephen Kitt : -T 사용에 대해 언급했지만 답변의 코드 스 니펫에서 찾을 수 없습니다. 내가 오해하거나 무언가를 놓치고 있습니까?
Guizmoo03

@ Guizmoo03 아마도 스 니펫을 소개하는 "Alternatively"를 놓쳤을 것입니다. 첫 세 단락은 설명 -T하지만 내 대답의 끝에는 사용하지 않는 다른 해결책이 제시됩니다 -T.
Stephen Kitt

-1

여기서 일어나는 일을 가장 잘 말할 수있는 것은 두 번째 단계에서 ln명령이 cp또는 처럼 작동 mv한다는 것입니다. 존재하는 경우 <대상>을 만듭니다. (이것은 "슬래쉬 닷"트릭이 피하는 것입니다. 즉, <destination>이 존재하고 디렉토리인지 확인합니다).
그러나 나는 틀릴 수 있습니다.

두 경우 모두 작동하는 것 같습니다

ln -sfv --no-dereference /tmp/test_symlink/repo/resources/snippets/ foo/snippets
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.