파일 설명자 복사본 없이 stdout과 stderr을 동일한 파일로 리디렉션하는 것이 안전합니까?

파일 설명자 복사본 없이 stdout과 stderr을 동일한 파일로 리디렉션하는 것이 안전합니까?

빈 디렉토리로 시작합니다.

$ touch aFile
$ ls
aFile

그런 다음 두 개의 매개변수가 있는데 ls그 중 하나는 이 디렉토리에 없습니다. output나는 >>동시 쓰기를 피하기 위해 이것을 사용하고 있습니다.

$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile

이것은 작동하는 것 같습니다. 이 접근 방식에 위험이 있나요?

답변1

아니요, 표준만큼 안전하지 않습니다 >>bar 2>&1.

당신이 글을 쓸 때

foo >>bar 2>>bar

bar열린 파일을 두 번 사용하여 O_APPEND각각 고유한 상태(포인터, 열기 모드 등)를 갖는 두 개의 완전히 독립적인 파일 개체[1]를 만듭니다 .

2>&1이는 단순히 시스템 호출을 호출하는 것과는 매우 다르며 dup(2)동일한 파일 객체의 stderr 및 stdout을 상호 교환 가능하게 별칭으로 만듭니다.

이제 질문이 있습니다.

O_APPEND여러 프로세스가 동시에 파일에 데이터를 추가하면 NFS 파일 시스템에서 파일이 손상될 수 있습니다. 이는 NFS가 파일 추가를 지원하지 않기 때문에 클라이언트 커널이 이를 에뮬레이트해야 하는데 이는 경쟁 조건 없이는 수행할 수 없습니다.

일반적으로 동시에 두 개의 서로 다른 위치에서 파일이 기록될 확률은 매우 낮다고 가정할 수 있습니다 bar. foo >>bar 2>&1그러나 당신은 >>bar 2>>bar아무 이유 없이 그것을 수십 배나 늘렸습니다.

[1] POSIX 용어의 "파일 설명 열기".

답변2

네가 이걸 하면 무슨 일이 일어날까?

some_command >>file 2>>file

예, file추가를 위해 두 번 열립니다. POSIX 파일 시스템에서는 안전합니다. 추가를 위해 파일이 열려 있는 동안 발생하는 쓰기는 데이터가 표준 출력 또는 표준 오류 스트림에서 나오는지 여부에 관계없이 파일 끝에서 발생합니다.

이는 기본 파일 시스템의 원자적 추가 쓰기 작업 지원에 의존합니다. 일부 파일 시스템(예: NFS)은 원자성 추가를 지원하지 않습니다. 예를 들어 질문을 참조하십시오."UNIX에서 파일이 원자적으로 추가됩니까?"StackOverflow에서.

사용

some_command >>file 2>&1

NFS에서도 작동합니다.

그러나

some_command >file 2>file

쉘이 출력 파일을 두 번 자르고 두 스트림 중 하나에서 발생하는 모든 쓰기는 안전하지 않습니다.씌우다다른 스트림에서 이미 쓴 데이터입니다.

예:

$ { echo hello; echo abc >&2; } >file 2>file
$ cat file
abc
o

문자열이 먼저 쓰여지고 hello(종료 줄 바꿈 포함) abc표준 오류에서 줄 바꿈이 뒤따르는 문자열이 덮어쓰기됩니다 hell. 결과는 줄 바꿈이 있는 문자열이고 그 뒤에 abc첫 번째 출력 echo의 나머지 부분 o과 줄 바꿈 기호가 옵니다. .

문자열이 마지막에 기록되었고 그보다 길기 때문에 두 개의 랩을 교환하면 출력 파일 echo만 생성됩니다 . 리디렉션이 발생하는 순서는 중요하지 않습니다.helloabc

좀 더 관용적인 방법을 사용하는 것이 더 좋고 안전할 것입니다.

some_command >file 2>&1

답변3

그것은 당신이 달성하려는 것에 달려 있습니다. 출력과 동일한 파일에 오류가 있을 수 있는지 여부는 사용자에게 달려 있습니다. 이는 단순히 쉘의 기능을 사용하여 텍스트를 파일에 저장하므로 필요에 따라 리디렉션할 수 있습니다. 절대적인 예 또는 아니요는 없습니다. Linux의 모든 작업은 여러 가지 방법으로 수행될 수 있으므로 ls notExistingFile existingFile >> output 2>&1 다음 질문에 대답하겠습니다. 리디렉션 자체에 관한 한 그렇습니다. 완전히 안전합니다.

관련 정보