출력을 파일로 리디렉션하면 파일에 잠금이 적용되나요?

출력을 파일로 리디렉션하면 파일에 잠금이 적용되나요?

나에게 명령이 있다면

$ ./script >> file.log

두 번 호출되고 첫 번째 호출이 끝나기 전에 두 번째 호출이 발생하면 어떻게 되나요?

첫 번째 호출이 출력 파일에 대해 배타적 잠금을 얻나요? 그렇다면 쓰기를 시도할 때 두 번째 스크립트가 실패합니까, 아니면 쉘이 출력을 승인하고(스크립트가 종료되도록 허용) 오류를 발생합니까?

아니면 로그 파일이 두 번 기록됩니까?

답변1

Unix 시스템은 대체로 필수 잠금을 피합니다. 커널이 사용자 프로그램에 의한 수정에 대해 파일을 잠그는 경우가 있지만 단순히 다른 프로그램에 의해 작성되는 경우에는 그렇지 않습니다. 프로그램이 파일에 쓰고 있기 때문에 유닉스 시스템은 파일을 잠그지 않습니다.

스크립트의 동시 인스턴스가 서로의 발가락을 밟지 않도록 하려면 다음과 같은 명시적인 잠금 메커니즘을 사용해야 합니다.flock lockfile.

추가하기 위해 파일을 열면 >>각 프로그램은 항상 파일 끝에 쓰도록 보장됩니다. 따라서 여러 인스턴스의 출력은 서로 덮어쓰지 않으며, 차례로 쓰기를 수행하는 경우 출력은 쓰기와 동일한 순서가 됩니다.

일어날 수 있는 나쁜 일은 인스턴스 중 하나가 여러 출력 청크를 작성하고 그것이 함께 나올 것으로 예상하는 경우입니다. 한 인스턴스의 연속 쓰기 사이에 다른 인스턴스가 자체 쓰기를 수행할 수 있습니다. 예를 들어, 인스턴스 1이 을 쓰고 foo인스턴스 2가 쓰고 hello인스턴스 2가 를 쓰면 bar파일에 가 포함됩니다 foohellobar.

프로세스는 시스템 호출을 호출할 때 효과적으로 파일에 씁니다 write. 호출은 write원자적입니다. 각 호출은 write다른 프로그램에 의해 중단되지 않는 일련의 바이트를 씁니다. 단일 호출로 효과적으로 쓸 수 있는 데이터 양에는 제한이 있는 경우가 많습니다 write. 크기가 더 큰 경우 데이터의 시작 부분만 기록되고 애플리케이션은 write다시 호출해야 합니다. 또한, 많은 프로그램이 수행됩니다.버퍼링: 메모리 영역에 데이터를 축적한 다음 이 데이터를 한 덩어리로 씁니다. 일부 프로그램은 완전한 라인 또는 기타 의미 있는 분리 후에 출력 버퍼를 플러시합니다. 이러한 프로그램을 사용하면 너무 길지 않은 한(최대 몇 킬로바이트, 이는 OS에 따라 다름) 전체 라인이 중단되지 않을 것으로 기대할 수 있습니다. 프로그램이 의미 있는 지점에서 플러시하지 않고 버퍼 크기만 기준으로 플러시하는 경우 한 인스턴스에서 4kB, 다른 인스턴스에서 4kB, 첫 번째 인스턴스에서 다시 4kB 등을 볼 수 있습니다.

답변2

추가를 의미하는 를 사용하고 있으므로 >>각 인스턴스의 각 출력 줄은 발생한 순서대로 추가됩니다.

스크립트 출력이 각각 1초의 지연을 두고 인쇄되고 1\n인스턴스 5\n2가 2.5초 후에 시작되면 다음과 같은 결과를 얻게 됩니다.

1
2
1
3
2
4
3
5
4
5

따라서 귀하의 질문에 대답하자면: 아니요.

관련 정보