저는 터미널을 사용하여 다음과 같이 여러 명령의 출력을 동시에 동일한 파일로 파이프합니다.
cmd1 | tee -a /tmp/file
cmd2 | tee -a /tmp/file
cmd3 | tee -a /tmp/file
사용해도 안전한가요? 이 방법을 사용할 때 데이터 손실이나 읽기/쓰기 권한 문제가 있습니까?
편집하다:출력 믹스에 만족합니다. 모든 것이 파일에 기록되는지 확인하고 싶습니다. 두 명령이 동시에 파일에 출력을 쓰려고 하면 충돌이 발생합니까?
답변1
append
tee with ( ) 모드를 사용하면 -a
추가 작업이 없는 파일 시스템(예: NFS)을 제외하고 데이터 손실 위험이 없습니다. append
모드 에서는 tee
플래그가 있는 파일을 엽니다 O_APPEND
.
$ echo 1 | strace tee -a /tmp/file 2>&1 | grep open | grep /tmp/file
openat(AT_FDCWD, "/tmp/file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
에서 man 2 openat
:
O_APPEND The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modification of the file offset and the write operation are performed as a single atomic step.
핵심 문장은파일 오프셋의 수정 및 쓰기 작업은 단일 원자 단계로 수행됩니다.. write()
인스턴스에 관계없이 각 호출은 tee
파일 오프셋을 파일 끝으로 원자적으로 배치한 다음 데이터를 쓰도록 보장됩니다.
매뉴얼 openat
페이지에는 이 사용 패턴이 NFS 파일 시스템에서 안전하지 않다고 명시되어 있습니다(앞서 언급한 바와 같이):
O_APPEND may lead to corrupted files on NFS filesystems if more than one process appends data to a file at once. This is be‐ cause NFS does not support appending to a file, so the client kernel has to simulate it, which can't be done without a race condition.