busybox의 디렉토리에 대한 심볼릭 링크를 원자적으로 변경하는 방법은 무엇입니까?

busybox의 디렉토리에 대한 심볼릭 링크를 원자적으로 변경하는 방법은 무엇입니까?

원자적으로(가능한 한 가깝게) 심볼릭 링크를 변경하려고 합니다. 나는 시도했다:

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 -TstraceLinux에만 해당됩니다.

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'

내 생각에는 이 작업을 두 단계로 수행해야 한다고 생각합니다. 이전 심볼릭 링크를 삭제하고 다시 생성하는 것입니다.

관련 정보