> /-가> / dev / null보다 효율적입니까?


58

어제 본인은 이 SO 의견을 쉘에서 (적어도 있다고한다 bash) >&-"와 같은 결과가 있습니다" >/dev/null.

이 의견은 실제로 ABS 안내서 를 정보의 출처로 언급합니다 . 그러나 그 소스는 >&-구문이 "파일 디스크립터를 닫는다" 고 말합니다 .

파일 디스크립터를 닫고 널 디바이스로 경로 재지 정하는 두 가지 조치가 완전히 동등한 지 여부는 확실하지 않습니다. 그래서 내 질문은 : 그들이 있습니까?

표면적으로 설명자를 닫는 것은 문을 닫는 것과 같지만 널 장치로 리디렉션하면 림보의 문이 열립니다! 닫힌 문을 보면 아무것도 버리려고하지 않지만 열린 문을 보면 내가 할 수 있다고 가정하기 때문에 두 사람은 나에게 똑같이 보이지 않습니다.

즉, 실제로 파일의 모든 바이트를 처리하고 잊어 버릴 수 있는 >/dev/null수단이 있는지 항상 궁금 했습니다. 다른 한편으로, 쉘이 닫힌 파일 디스크립터를 만나면 단순히 아무것도 쓰지 않을 것이라고 생각하는 경향이 있지만 확실하지는 않지만 모든 바이트를 읽을 지 여부 는 여전히 의문 입니다.cat mybigfile >/dev/null/dev/nullcat

이 코멘트는 말했다 >&->/dev/null" 해야 동일"하지만 나에게 이렇게 울려 퍼지는 대답하지 않습니다. 표준 또는 소스 코어와 관련하여 더 권위있는 답변을 원합니다.


내가 자선을 원한다면, 그 의견은 그들이 같은 방식으로 구현되었다는 것을 의미하지는 않으며, 둘 다 당신이 프로그램의 결과를 보지 못하게 막는 것과 같은 최종 결과를 가지고 있다고 말하고 싶습니다.
Barmar

답변:


71

아니요, 파일 디스크립터 0, 1 및 2를 닫고 싶지 는 않습니다 .

이렇게하면 응용 프로그램이 파일을 처음 열 때 stdin / stdout / stderr가됩니다 ...

예를 들어, 다음과 같은 경우 :

echo text | tee file >&-

tee(비지 박스 같은 적어도 일부 구현 ') 쓰기 위해 파일을 열어,이 파일 기술자 1 (표준 출력)에 공개됩니다. 그래서 두 번 tee쓸 것입니다 :textfile

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "text\n", 8193)                 = 5
write(1, "text\n", 5)                   = 5
write(1, "text\n", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

보안 취약점을 일으키는 것으로 알려져 있습니다. 예를 들어 :

chsh 2>&-

그리고 chsh(setuid 애플리케이션)은에 오류 메시지를 작성할 수 있습니다 /etc/passwd.

일부 도구 및 일부 라이브러리는이를 방지하려고합니다. 예를 들어 teebusybox tee는 작성하지 않고 쓰기 위해 열린 파일에 0, 1, 2가 할당 된 경우 GNU 는 파일 디스크립터를 2 이상으로 이동합니다 .

대부분의 도구가 stdout에 쓸 수없는 경우 (예 : 열려 있지 않기 때문에) 현지화 파일을 열고 구문 분석하는 추가 처리를 의미하는 사용자의 언어로 stderr에 오류 메시지를보고합니다. 효율성이 크게 떨어지고 프로그램이 실패 할 수 있습니다.

어쨌든 더 효율적이지 않습니다. 프로그램은 여전히 write()시스템 호출을 수행합니다 . 첫 번째 write()시스템 호출 실패 후 프로그램이 stdout / stderr에 쓰기를 포기하는 경우에만 더 효율적일 수 있지만 프로그램은 일반적으로 그렇게하지 않습니다. 일반적으로 오류와 함께 종료되거나 계속 시도합니다.


4
마지막 단락이 맨 위에 있으면 (OP의 질문에 가장 직접적으로 답변하기 때문에)이 답변이 더 나을 것이라고 생각한 다음 주로 효과가 있었지만 왜 나쁜 생각인지 논의했습니다. 그러나 나는 그것을 가지고 투표 할 것이다. ;)
CVn

@ StéphaneChazelas : Michael이 말했듯이, 마지막 단락을 기대했을 것입니다. 그래서 FD를 닫는 것이 실제로 유용 할 때 부수적 인 질문이 될 것 같습니다. 아니면 별도의 질문으로해야합니까?
jamadagni


1
@jamadagni Stéphane이 제공 한 링크가 질문에 대답하지 못하면 별도의 질문의 시작 부분처럼 들리므로 두 방법의 상대 효율성과 직접 관련이 없습니다.
CVn

1
Stephane은 마지막 단락이 맨 위에 표시되면 눈에 잘 띄지 않기 때문에이 중요한 보안 경고로 시작한다는 것에 감사드립니다. 나에게서 +1
Olivier Dulac

14

IOW는 항상 파일의 모든 바이트를 실제로 처리하고 잊어 버릴 수 있는 >/dev/null수단인지 궁금 했습니다.cat mybigfile >/dev/null/dev/null

귀하의 질문에 대한 완전한 답변은 아니지만 위의 방법이 작동합니다.

cat명명 된 파일 또는 명명 된 파일이없는 경우 표준 입력을 읽고 명명 된 마지막 파일에서 EOF (표준 입력 포함)가 발생할 때까지 해당 내용을 표준 출력에 출력 합니다. 즉 작업.

추가 >/dev/null하면 표준 출력을 / dev / null로 리디렉션합니다. 그것은 특별한 파일 (장치 노드)로 쓰여진 것을 버리고 (읽을 때 즉시 EOF를 반환합니다). I / O 리디렉션은 각각의 개별 응용 프로그램이 아니라 셸에서 제공하는 기능이며 / dev / null 이라는 이름 에는 마법적인 것이 없으며 대부분의 Unix 계열 시스템 에는 존재하는 것만 있습니다 .

그것은 장치 노드의 특정 메커니즘이 운영 운영 체제 시스템,하지만 고양이 (A GNU 시스템에서,로 coreutils을 의미한다)에서 차이가 있음을 크로스 플랫폼입니다주의하는 것도 중요하다 (동일한 소스 코드를 실행하는 데 필요한 최소한 리눅스와에 Hurd) 따라서 특정 운영 체제 커널에 종속 될 수 없습니다. 또한 다른 이름으로 / dev / null 별칭 (Linux에서는 주 / 부 장치 번호가 동일한 장치 노드를 의미 함)을 만들면 여전히 작동합니다. 그리고 항상 동일하게 동작하는 다른 곳 (예 : / dev / zero)을 작성하는 경우가 있습니다.

그것은 cat/ dev / null의 특별한 속성을 알지 못하기 때문에 처음에는 리디렉션을 알지 못할 수도 있지만 여전히 똑같은 작업을 수행해야 합니다. 명명 된 파일을 읽고 내용을 출력합니다. 해당 파일을 표준 출력에 추가합니다. 표준 출력이 cat빈 공간으로 들어가는 것은 cat그 자체가 우려하는 것이 아닙니다 .


2
답변을 확장하려면 : 예, cat mybigfile > /dev/null원인이됩니다 cat의 모든 바이트를 읽어 bigfile메모리에. 그리고 모든 n바이트에 대해을 호출 write(1, buffer, n)합니다. cat프로그램에 알려지지 않은 , write의지는 절대적으로 아무것도하지 않습니다 (어쩌면 사소한 부기를 제외하고). 쓰기 /dev/null는 모든 바이트를 처리 할 필요는 없습니다.
G-Man

2
/ dev / null 장치의 Linux 커널 소스를 읽을 때 날아 갔다는 것을 기억합니다. 나는 free () 버퍼 등의 정교한 시스템이있을 것으로 기대했지만, 기본적으로 return ()입니다.
Brian Minton

4
@ G-Man : 모든 경우에 사실임을 보증 할 수는 없습니다. 지금 증거를 찾을 수없는,하지만 난 하나의 몇 가지 구현을 호출 cat또는 cp그에 의해 작동합니다 mmap호출 한 후, 메모리에 소스 파일의 큰 덩어리를 보내고 write()매핑 된 지역에. 당신이 기록 된 경우 /dev/nullwrite()호출은 소스 파일의 페이지에 오류가있는없이 한 번에 반환, 그래서 실제로 디스크에서 읽을되지 않을 것입니다.
Nate Eldredge

2
또한 GNU와 같은 cat것은 많은 플랫폼에서 실행되지만 소스 코드를 간단히 살펴보면 많은 플랫폼을 볼 수 있습니다 #ifdef. 문자 그대로 모든 플랫폼에서 실행되는 동일한 코드는 아니며 시스템에 따라 많은 섹션이 있습니다.
Nate Eldredge

@ NateEldredge : 재미있는 점이지만, 나는 단지 Michael의 대답에 기초하고 있었으므로 Michael과 모순되는 것처럼 나를 모순하지 않습니다.
G-Man
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.