원자적으로(가능한 한 가깝게) 심볼릭 링크를 변경하려고 합니다. 나는 시도했다:
ln -sf other_dir existing_symlink
이것은 단지 Execution_symlink가 가리키는 디렉토리에 새로운 심볼릭 링크를 넣습니다.
ln -sf other_dir new_symlink
mv -f new_symlink existing_symlink
이는 동일한 작업을 수행합니다. 즉, 심볼릭 링크를 디렉터리로 이동합니다.
cp -s other_dir existing_symlink
디렉터리이기 때문에 거부됩니다.
나는 이것이 이것을 위해 설계되었다는 것을 읽었 mv -T
지만 busybox에는 해당 플래그가 없습니다 -T
.
답변1
이것할 수 있는rename(2)
먼저 임시 이름으로 새 심볼릭 링크를 만든 다음 이전 심볼릭 링크를 한 번에 완전히 덮어쓰는 방식으로 이 작업을 자동으로 수행할 수 있습니다. ~처럼매뉴얼 페이지상태:
만약에새로운 길심볼릭 링크를 참조하면 해당 링크를 덮어쓰게 됩니다.
셸에서는 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 -T
은 strace
Linux에만 해당됩니다.
FreeBSD에서는 mv -h
같은 의미로 사용됩니다.
답변2
Arto가 중단한 부분부터 다시 시작하는 것은 전적으로 가능하며, 그렇지 않더라도 대상 디렉터리와 동일한 이름을 가진 새 심볼릭 링크를 만들어 대상의 상위 디렉터리에 넣으면 mv -T
됩니다 .mv
mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./
(를 통한 코드 예제http://axiscorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/)
답변3
시도해 보셨나요 ln -snf
?
-n
대상이 디렉토리에 대한 심볼릭 링크인 경우 이 옵션은 대상 아래에 쓰는 대신 대상을 덮어씁니다.
건배
답변4
원자 연산을 수행하는 방법을 이해하지 못합니다. 매뉴얼 페이지에는 대상이 이미 존재하는지 여부를 symlink(2)
제공한다고 나와 있습니다 . EEXIST
커널이 원자성 작업을 지원하지 않으면 사용자 공간 제한은 중요하지 않습니다.
mv -T
가지고 있다고 해도 그게 어떻게 도움이 될지 모르겠어요 . GNU mv를 사용하여 일반 Linux 상자에서 다음을 시도해 보세요.
$ mkdir a b
$ ln -s a z
$ mv -T b z
mv: cannot overwrite non-directory `z' with directory `b'
내 생각에는 이 작업을 두 단계로 수행해야 한다고 생각합니다. 이전 심볼릭 링크를 삭제하고 다시 생성하는 것입니다.