rename(2)
다음이 호출되기 때문에 mv
원자적이라고 가정하는 것이 안전합니까 ?
$ mv /home/me/someDir /tmp/toBeDeleted
$ rm -rf /tmp/toBeDeleted
답변1
이것mv
주문하다~라고 불리는rename
시스템 호출, 원자성을 보장합니다. 그러나 두 가지 예외가 있습니다.
- 소스와 타겟이 서로 다른 파일 시스템에 있는 경우(
/home
대체적으로 일반적임)/tmp
소스 트리를 타겟에 복사한 다음 소스 트리를 삭제하는 방식으로 작동rename
합니다 .mv
이것은 분명히 원자적이지 않습니다. rename
일부 NFS 구현과 같은 일부 파일 시스템은 원자적이지 않습니다 . "일반" 로컬 파일 시스템에서rename
이는 원자적입니다.
답변2
디렉터리가 단일 파일 시스템으로 마운트된 동일한 하드웨어 파티션에 있는 경우, 무언가를 이동하는 것은 실제로는 다른 경로로 이름을 바꾸는 것입니다. 그러나 그렇지 않은 경우에는 거기에 있는 모든 파일을 읽고 복사해야 하므로 이동의 어떤 부분도 원자적이지 않습니다. Gilles가 지적했듯이 POSIX는 이것이 개별 파일 시스템의 경우임을 지정합니다.
strace
그 외에도 확인을 사용한 빠른 확인에는 시스템 호출이 mv
사용됩니다 ( 명령줄 유틸리티와 혼동하지 마세요). 이렇게 하면 사용자 공간 관점에서 디렉토리가 원자적 으로 만들어집니다. 다음과 같은 경우 시스템 호출에서 EBUSY 오류가 발생합니다 .rename()
rename
mv
rename()
oldpath 또는 newpath는 일부 프로세스에서 사용 중이거나(현재 작업 디렉터리, 루트 디렉터리 또는 읽기용으로 열려 있기 때문에) 시스템에서 사용 중인 디렉터리입니다(예: 마운트 지점). 시스템에서는 이를 실수로 간주합니다. (이 경우에는 EBUSY를 반환할 필요가 없습니다. 어쨌든 이름을 바꾸는 것은 괜찮았을 것입니다. 그러나 시스템이 그러한 경우를 처리할 수 없는 경우에는 허용됩니다.)
에서 man 2 rename
. 여기서 "원자성"에 대한 연결은 디렉터리에서 작업하는 다른 프로세스를 중단할 수 없고 다른 프로세스도 이를 중단할 수 없다는 것입니다. 추적을 이기면 잘못된 경로/찾을 수 없음 유형 오류가 발생하게 됩니다.
답변3
이 두 답변은 본질적으로 동일한 내용을 말하지만 삭제의 한 측면에만 중점을 둡니다.
쉘의 작업 디렉토리가 이름이 바뀌거나 이동된 디렉토리 트리에 있으면 계속됩니다.바라보다그리고사용실제로 삭제될 때까지 해당 파일을 삭제하세요. 따라서 쉘은 다양한 삭제 상태의 파일을 확인하므로 이름 바꾸기/이동( 가능한예"원자"그 자체)는아니요파일의 모든 사용자의 관점에서 볼 때 이는 원자 형태의 삭제입니다. 이는 처음부터 디렉토리 트리 외부에 쉘이 있었던 사용자에게만 영향을 미칩니다.
쉘은 쉘이 위치한 디렉토리에 대한 자체 정보를 유지합니다. 이는 일부 구성에서 현재 디렉터리를 실제 경로를 결정하는 데 필요한 디렉터리 정보 체인을 읽을 수 있는 권한이 없는 디렉터리로 변경할 수 있기 때문입니다(예: 보호된 디렉터리에 대한 심볼릭 링크를 통해).