연결된 명령은 원자적입니까?

연결된 명령은 원자적입니까?

지속적으로 파일에 쓰는 프로세스가 있고 루트로 파일을 제어하고 싶다면 다음과 같이 할 수 있습니다.

sudo rm somefile; sudo touch somefile

이 두 명령 사이에 파일에 추가 프로세스를 추가할 수 있습니까? 그렇다면 그 동안 다른 명령이 실행되지 않도록 하는 방법이 있습니까?

답변1

연결된 명령줄은 기본적으로 작은 쉘 스크립트입니다. 일반적인 fork+exec 프로세스를 사용하여 첫 번째 명령을 실행하고 종료될 때까지 기다린 다음 동일한 방식으로 두 번째 명령을 실행합니다. 이 두 명령 사이에서 쉘은 기록 및 처리에 임의의 시간을 소비합니다. 이 시간 동안 일반적인 다중 처리가 발생하고 임의의 다른 프로세스가 임의의 다른 작업을 수행할 수 있습니다. 그래서 대답은 "아니요"입니다. (이렇게 하면 디렉터리 항목은 somefile사라지지만 파일 자체는 닫힐 때까지(프로세스에 의해 열렸기 때문에) 여전히 존재합니다. 그때까지는 파일이 사용하는 디스크 공간을 회수하지 않습니다. 동시에 이 touch명령은 동일한 이름과 경로를 가진 관련 없는 새 파일을 생성합니다.

파일의 소유권을 루트로 변경하려면 그렇게 하면 됩니다 sudo chown root:root somefile(이것이 열린 파일 핸들이 있는 프로세스에 어떤 영향을 미칠지는 모르겠지만). 현재 파일 내용을 삭제하려면 다음을 시도해 보십시오 truncate -s 0 somefile(실행 중인 프로세스는 현재 비어 있는 파일에 계속 추가됩니다). 다른 일이라면 무엇을 하고 싶은지 명확히 하세요.

답변2

아니요. 명령 rm다음에 touch명령이 오는 것은 전혀 원자적이지 않습니다. 두 명령 사이의 시간 간격은 상당히 깁니다. 아마도 밀리초 범위일 것입니다. 그 동안 많은 일이 일어날 수 있습니다. 운이 좋지 않으면 sudo 자격 증명이 만료될 수도 있습니다.

단일 프로그램을 호출 unlink하고 open호출하면 경합 기간이 더 짧아지지만 여전히 발생할 수 있습니다.

더 안전한 접근 방식은 임시 이름으로 새 파일을 만들고 rename시스템 호출을 사용하는 것입니다. 시스템 호출을 사용하여 이름을 "재정의"하는 것은 rename원자성이 보장됩니다. 이는 touch및 를 사용하여 달성 할 수 있습니다 mv.

그러나 쓰기 위해 이전 파일을 연 프로세스는 이전 파일이 삭제된 후에도 오랫동안 파일에 계속 쓸 수 있습니다. unlink이는 삭제된 파일과 삭제된 파일 모두에 발생합니다 rename.

답변3

프로세스가 읽기 위해 파일 핸들을 열면 소유권이나 권한으로 무엇을 하는지는 중요하지 않습니다. 프로세스는 계속해서 파일에 액세스할 수 있습니다. 파일을 삭제할 수도 있으며 프로세스는 파일 핸들을 통해 계속해서 해당 파일에 액세스할 수 있습니다.

권한을 파일 핸들을 얻기 위한 제어 게이트로 생각하십시오.

파일을 자동으로 생성하려면 다음을 수행하지 마십시오.

sudo rm somefile
sudo touch somefile

다음을 고려할 수 있습니다.

sudo touch anotherfile
sudo perl -e "rename 'anotherfile', 'somefile'"

(사용하고 싶지만 시스템 호출이 호출된다는 것을 보장 하는 명령문을 somefile찾을 수 없습니다 .anotherfilemv -frename(2)


어쩌면 "제어 파일"의 의미를 설명하기 위해 질문을 업데이트할 수 있습니다. 당신은XY 문제여기.

답변4

아니요, 하지만

sudo rm somefile; sudo touch somefile

대부분의 경우 안전합니다.

대부분의 프로세스는 파일을 연 다음 얻은 파일 설명자를 사용하여 파일 내용에 액세스합니다.

프로세스가 sh에서 파일을 여는 경우:

 exec 3>somefile

그런 다음 다른 프로세스는 자유롭게 somefile의 링크를 해제(=삭제)할 수 있으며, 첫 번째 프로세스(이 경우 3)가 somefile을 연 파일 설명자는 현재 불확실한 상태 파일인 somefile의 원래 내용을 계속 참조합니다.

sudo touch somefile

관련되지 않은 새 somefile이 생성되고 이전 somefile이 열려 있고 이제 파일 설명자만 사용하여 이를 참조하는 모든 프로세스는 영향을 받지 않습니다. 이는 현재 불확실한 상태 문서에 있는 다른 파일을 참조하기 때문입니다.

루트가 아닌 프로세스가 이름으로 파일을 참조하려고 하면 새 파일이 루트의 소유이므로 EPERM 오류가 발생합니다.

Linux에는 동일한 사용자(예: 루트)의 여러 프로세스가 파일을 손상시키는 것을 방지하려는 경우 필수 및 권장 파일 잠금 기능이 있습니다. flock권고 파일 잠금을 위한 쉘 스크립트에서 이 명령을 사용할 수 있습니다 (자세한 내용은 맨페이지 참조).

관련 정보