it-swarm-ko.tech

busybox의 디렉토리에 대한 심볼릭 링크를 원자 적으로 어떻게 변경합니까?

심볼릭 링크를 원자 적으로 변경하려고합니다. 난 노력 했어:

ln -sf other_dir existing_symlink

그것은 existing_symlink가 가리키는 디렉토리에 새 심볼릭 링크를 넣습니다.

ln -sf other_dir new_symlink
mv -f new_symlink existing_symlink

동일한 작업을 수행했습니다. 심볼릭 링크를 디렉토리로 옮겼습니다.

cp -s other_dir existing_symlink

디렉토리이기 때문에 거부합니다.

mv -T이 (가) 만들어 졌다고 읽었지만 busybox에는 -T 플래그가 없습니다.

18
Shawn J. Goff

나는 당신이 어떻게 원자 연산을 할 수 있는지 모르겠습니다. symlink(2)의 man 페이지에는 타겟이 이미 존재하는 경우 EEXIST가 표시됩니다. 커널이 원자 연산을 지원하지 않는 경우 사용자 영역 제한은 무관합니다.

나는 또한 어떻게 mv -T 도움이됩니다. GNU mv :

$ mkdir a b
$ ln -s a z
$ mv -T b z
mv: cannot overwrite non-directory `z' with directory `b'

이 작업은 두 단계로 수행해야한다고 생각합니다. 이전 심볼릭 링크를 제거하고 다시 만듭니다.

1
Warren Young

can 실제로 rename(2)을 사용하여 원자 적으로 수행 할 수 있습니다. 먼저 임시 이름으로 새 심볼릭 링크를 만든 다음 이전 심볼릭 링크를 완전히 덮어 씁니다. 한 번에. man page 는 다음과 같이 설명합니다.

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는 모두 Linux 전용입니다.

FreeBSD에서는 mv -h를 번갈아 사용합니다.

43
Arto Bendiken

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://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/ )를 통해 가져온 코드 예제

8
mssaxm

ln -snf을 (를) 사용해 보셨습니까?

-n 옵션은 대상이 디렉토리에 대한 심볼릭 링크 일 때 대상 아래에 쓰지 않고 덮어 씁니다.

건배

3
sokai