디렉토리에 대한 심볼릭 링크를 생성하는 데 사용할 수 있는 멱등성 명령은 무엇입니까?

디렉토리에 대한 심볼릭 링크를 생성하는 데 사용할 수 있는 멱등성 명령은 무엇입니까?

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

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

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

foo/나는 snippets 라는 이 디렉토리에 대한 심볼릭 링크를 만들고 싶습니다 /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

이런 일이 발생하는 이유는 무엇이며 후속 호출에서 이러한 이상한 효과가 발생하지 않도록 명령을 수정하려면 어떻게 해야 합니까?

답변1

이를 위해서는 링크 이름을 항상 디렉토리가 아닌 원하는 링크 이름으로 처리하도록 -T지시하는 이 옵션을 사용해야 합니다 .ln

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

이것은 -TGNU-ism(적어도 POSIX에는 없음)이지만 이미 사용하고 있고 -vGNU-ism이므로 문제가 되지 않을 것 같습니다.

또는 상위 디렉터리를 링크 이름으로 지정하면 링크가 항상 해당 디렉터리에 (재)생성됩니다.

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

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

답변2

내가 알 수 있는 가장 좋은 점은 두 번째 단계에서 ln명령이 cpor 처럼 동작한다는 mv것입니다. 즉, <destination>에서 "디렉토리"를 보면 그 안에 파일을 넣을 것이고, 그렇지 않으면 <destination> >이 존재하지 않으면 파일을 넣을 것입니다. <목적지>를 생성합니다. (이것은 "slashdot" 트릭이 피하는 것입니다. 즉, <destination>이 존재하고 디렉토리인지 확인합니다).
그러나 나는 틀릴 수 있습니다.

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

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

관련 정보