[unix] 심볼릭 링크가 생성 된 후 가리키는 것을 변경할 수 있습니까?

어떤 운영 체제에서 이전 링크를 해제하고 새 링크를 만드는 것 외에 기호 링크 (symlink)가 참조하는 경로 이름을 변경하는 메커니즘 (명령 줄 프로그램이 아닌 시스템 호출)을 제공합니까?

POSIX 표준은 그렇지 않습니다. Solaris 10은 그렇지 않습니다. MacOS X 10.5 (Leopard)는 그렇지 않습니다. (나는 AIX 나 HP-UX도 마찬가지라고 확신합니다.이 Linux 시스템 호출 목록에서 볼 때 Linux에도 그러한 시스템 호출이 없습니다.)

하는 일이 있습니까?

(나는 대답이 “아니오”라고 예상하고 있습니다.)


부정적인 것을 증명하는 것이 어렵 기 때문에 질문을 재구성합시다.

아직 나열되지 않은 일부 (유닉스 계열) 운영 체제 readlink()에 이전 심볼릭 링크를 제거하고 새 심볼릭 링크를 생성하지 않고 심볼릭 링크 (에서 반환 된 문자열) 값을 다시 쓰기위한 시스템 호출이 없다는 것을 알고있는 경우 추가하십시오. 대답.



답변

AFAIK, 아니, 당신은 할 수 없습니다. 제거하고 다시 만들어야합니다. 실제로 심볼릭 링크를 덮어 써서 참조하는 경로 이름을 업데이트 할 수 있습니다.

$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 8 2009-09-23 17:12 test -> .profile

편집 : OP가 주석에서 지적했듯이 --force옵션을 사용하면 이전에 ln시스템 호출을 수행합니다 . 아래 는 내 리눅스 박스에 대한 출력입니다 .unlink()symlink()strace

$ strace -o /tmp/output.txt ln -s -f .bash_aliases test
$ grep -C3 ^unlink /tmp/output.txt
lstat64("test", {st_mode=S_IFLNK|0777, st_size=7, ...}) = 0
stat64(".bash_aliases", {st_mode=S_IFREG|0644, st_size=2043, ...}) = 0
symlink(".bash_aliases", "test")        = -1 EEXIST (File exists)
unlink("test")                          = 0
symlink(".bash_aliases", "test")        = 0
close(0)                                = 0
close(1)                                = 0

그래서 최종 답은 “아니오”라고 생각합니다.

편집 : 다음은 2016 년경 unix.stackexchange.com 에서 Arto Bendiken의 답변 에서 복사되었습니다 .

실제로 원자 적으로 수행 할 수 rename(2)첫번째 임시 이름으로 새 심볼릭 링크를 생성하고 깔끔하게 한 번에 이전 심볼릭 링크를 덮어 쓰기. 매뉴얼 페이지에 다음과 같이 설명되어 있습니다.

경우 newpath를가 심볼릭 링크를 참조하는 링크를 덮어 쓰게됩니다.

셸에서 mv -T다음과 같이이 작업을 수행 합니다.

$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z

strace마지막 명령을 사용하여 실제로 rename(2)후드를 사용하고 있는지 확인할 수 있습니다 .

$ strace mv -T z.new z
lstat64("z.new", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("z.new", "z")                    = 0

참고 둘, 위의 것을 mv -Tstrace리눅스 다릅니다.

FreeBSD에서는 mv -h교대로 사용하십시오 .

편집자 주 : 이것이 Capistrano가 ~ 2.15 이후 수년 동안해온 방법입니다. 이 pull 요청을 참조하십시오 .


답변

그래 넌 할수있어!

$ ln -sfn source_file_or_directory_name softlink_name


답변

이전 심볼릭 링크를 명시 적으로 링크 해제 할 필요는 없습니다. 다음과 같이 할 수 있습니다.

ln -s newtarget temp
mv temp mylink

(또는 동등한 심볼릭 링크를 사용하고 호출 이름을 바꿉니다). 이름 변경은 원자 적이므로 명시 적으로 링크를 해제하는 것보다 낫습니다. 따라서 링크가 항상 이전 또는 새 대상을 가리킬 것임을 확신 할 수 있습니다. 그러나 이것은 원래 inode를 재사용하지 않습니다.

일부 파일 시스템에서 심볼릭 링크의 대상은 충분히 짧은 경우 inode 자체 (차단 목록 대신)에 저장됩니다. 이것은 생성 될 때 결정됩니다.

실제 소유자와 그룹이 중요하지 않다는 주장과 관련하여 Linux의 symlink (7) 는 중요한 경우가 있다고 말합니다.

lchown (2)을 사용하여 기존 심볼릭 링크의 소유자와 그룹을 변경할 수 있습니다. 심볼릭 링크의 소유권이 중요한 유일한 경우는 고정 비트가 설정된 디렉토리에서 링크를 제거하거나 이름을 바꿀 때입니다 (stat (2) 참조).

심볼릭 링크의 마지막 액세스 및 마지막 수정 타임 스탬프는 utimensat (2) 또는 lutimes (3)를 사용하여 변경할 수 있습니다.

Linux에서 심볼릭 링크의 권한은 어떤 작업에도 사용되지 않습니다. 권한은 항상 0777 (모든 사용자 범주에 대해 읽기, 쓰기 및 실행)이며 변경할 수 없습니다.


답변

위의 정답에 대한 경고 :

-f / –force 메서드를 사용하면 소스와 대상이 섞일 경우 파일이 손실 될 위험이 있습니다.

mbucher@server2:~/test$ ls -la
total 11448
drwxr-xr-x  2 mbucher www-data    4096 May 25 15:27 .
drwxr-xr-x 18 mbucher www-data    4096 May 25 15:13 ..
-rw-r--r--  1 mbucher www-data 4109466 May 25 15:26 data.tar.gz
-rw-r--r--  1 mbucher www-data 7582480 May 25 15:27 otherdata.tar.gz
lrwxrwxrwx  1 mbucher www-data      11 May 25 15:26 thesymlink -> data.tar.gz
mbucher@server2:~/test$
mbucher@server2:~/test$ ln -s -f thesymlink otherdata.tar.gz
mbucher@server2:~/test$
mbucher@server2:~/test$ ls -la
total 4028
drwxr-xr-x  2 mbucher www-data    4096 May 25 15:28 .
drwxr-xr-x 18 mbucher www-data    4096 May 25 15:13 ..
-rw-r--r--  1 mbucher www-data 4109466 May 25 15:26 data.tar.gz
lrwxrwxrwx  1 mbucher www-data      10 May 25 15:28 otherdata.tar.gz -> thesymlink
lrwxrwxrwx  1 mbucher www-data      11 May 25 15:26 thesymlink -> data.tar.gz

물론 이것은 의도 된 것이지만 일반적으로 실수가 발생합니다. 따라서 심볼릭 링크를 삭제하고 재 구축하는 것은 조금 더 많은 작업이지만 약간의 절약 효과도 있습니다.

mbucher@server2:~/test$ rm thesymlink && ln -s thesymlink otherdata.tar.gz
ln: creating symbolic link `otherdata.tar.gz': File exists

적어도 내 파일을 유지합니다.


답변

연결을 해제하고 새로운 것을 생성하면 결국 동일한 작업을 수행하지 않겠습니까?


답변

도움이되는 경우 : midnight commander (mc)와 함께 심볼릭 링크를 편집하는 방법이 있습니다. 메뉴 명령은 다음과 같습니다 (mc 인터페이스에서 프랑스어).

Fichier / Éditer le lien symbolique

다음으로 번역 될 수 있습니다.

File / Edit symbolic link

단축키는 Cx Cs입니다.

아마도 내부적으로 ln --force명령을 사용하는 것 같습니다.

이제는 한 번에 많은 심볼릭 링크를 편집하는 방법을 찾으려고합니다.


답변

기술적으로 기존 심볼릭 링크를 편집하는 기본 제공 명령이 없습니다. 몇 가지 짧은 명령으로 쉽게 달성 할 수 있습니다.

다음 은 기존 심볼릭 링크를 업데이트하기 위해 작성한 작은 bash / zsh 함수입니다 .

# -----------------------------------------
# Edit an existing symbolic link
#
# @1 = Name of symbolic link to edit
# @2 = Full destination path to update existing symlink with
# -----------------------------------------
function edit-symlink () {
    if [ -z "$1" ]; then
        echo "Name of symbolic link you would like to edit:"
        read LINK
    else
        LINK="$1"
    fi
    LINKTMP="$LINK-tmp"
    if [ -z "$2" ]; then
        echo "Full destination path to update existing symlink with:"
        read DEST
    else
        DEST="$2"
    fi
    ln -s $DEST $LINKTMP
    rm $LINK
    mv $LINKTMP $LINK
    printf "Updated $LINK to point to new destination -> $DEST"
}