Bash의 파일에서 원자 쓰기 작업 수행

Bash의 파일에서 원자 쓰기 작업 수행

후 the 난교문서,이것질문과이것Bash에서 파일에 원자적 쓰기(추가) 작업을 수행하는 방법이 아직 확실하지 않습니다. 여러 인스턴스에서 실행되는 스크립트가 있는데 어떤 시점에서는 데이터를 파일에 기록해야 합니다.

echo "$RESULT" >> `pwd`/$TEMP_DIR/$OUT_FILE

동시에 실행되는 모든 스크립트에서 이 파일에 대한 모든 쓰기를 원자성으로 만들려면 어떻게 해야 합니까(한 인스턴스의 데이터가 다른 인스턴스의 데이터와 겹치지 않도록)?

답변1

flock사람의 예를 사용해야 할 것 같습니다 (http://linux.die.net/man/1/flock)

(
flock -x 200

# Put here your commands that must do some writes atomically

) 200>/var/lock/mylockfile 

그리고 원자성이어야 하는 모든 명령을 ()에 넣습니다.

답변2

flock연동운전 방식 중 하나입니다. 이 유틸리티는 util-linux 도구 세트의 일부이며 Linux에서만 사용할 수 있습니다. 추가 유틸리티는 더 넓은 범위의 플랫폼에서 사용할 수 있으며 setlockDaniel J. Bernstein의 daemontools 패키지에 있는 유틸리티를 기반으로 합니다.

이 도구는 M. Kurenkov의 답변에 사용된 것과 약간 다른 모드에서 실행됩니다( flock작동하지만 해당 답변에서는 사용되지 않음). 하나는 setlock프로그램 을 호출하여체인 로드연동되어야 하는 명령에. setlock잠금 파일 자체를 열고 잠그며 해당 프로세스를 위해 파일 설명자를 열어 둡니다. 잠금은 프로세스가 존재하는 한 지속됩니다(체인의 후속 명령이 열려 있는 파일 설명자를 찾아 닫아 명시적으로 잠금을 해제하지 않는 한).

문제의 상황에 대해 출력 라인을 생성하는 명령을 연동하고 이것이 호출된다는 것을 인식해야 합니다.외부 echo쉘 내장 echo명령 대신:

setlock mylockfile echo "$RESULT" >> ./$TEMP_DIR/$OUT_FILE

이 경우, 추가 모드에서 출력 파일 열기를 연동할 필요가 없습니다. 그렇다면 파일은 잠금 내에서 열려야 하며 다음과 같은 방법을 사용해야 합니다.fdredir/redirfd:

setlock mylockfile fdredir --append 1 "./$TEMP_DIR/$OUT_FILE" echo "$RESULT"
필요한 경우 이는 쉘 함수로 전환될 수 있습니다.

outfile() { setlock mylockfile fdredir --append 1 "./$TEMP_DIR/$OUT_FILE" "$@" } 
[...]
outfile echoes "$RESULT"
또는 쉘 구문을 고수하고 인터록 하에서 실행되는 두 번째 쉘로 해석하도록 하십시오. 이는 쉘 변수가 환경 변수로 내보내지지 않는 경우 몇 가지 중요한 인용이 필요합니다.

setlock mylockfile sh -c 'echo '"$RESULT"' >> "./'$TEMP_DIR'/'$OUT_FILE'"'

물론 이는 출력 파일에 쓰는 것 외에 다른 것으로 일반화될 수 있습니다.

setlock mylockfile sh -c '...interlock 뭔가...'

관련 정보