나는 Bash에서 파이프 작업을 할 때 이것에 대해 더 이상 생각하지 않았습니다. 그러나 시스템 호출 파이프라인() 및 포크()를 사용하는 일부 C 코드 예제를 읽을 때 익명 파이프와 명명된 파이프 모두를 이해하는 방법이 궁금했습니다.
사람들은 "Linux/Unix의 모든 것은 파일이다"라는 말을 자주 듣습니다. 파이프가 실제로 파일인지 궁금합니다. 연결의 한 부분은 파이프 파일에 쓰고 다른 부분은 파이프 파일에서 읽습니까? 그렇다면 익명 파이프에 대한 파이프 파일은 어디에 생성됩니까? /tmp, /dev 또는...?
그러나 명명된 파이프 예제를 통해 파이프를 사용하면 임시 파일을 명시적으로 사용하는 것보다 공간 및 시간 성능 측면에서 이점이 있다는 것도 알게 되었습니다. 아마도 파이프 구현에 파일이 포함되지 않기 때문일 것입니다. 그리고 파이프는 파일과 같은 데이터를 저장하지 않는 것 같습니다. 그래서 나는 파이프가 실제로 파일이라고 생각합니다.
답변1
성능 질문과 관련하여 디스크 IO가 필요하지 않기 때문에 파이프가 파일보다 더 효율적입니다. 따라서 이것은 사실이 아닐 수도 있습니다 cmd1 | cmd2
(RAM 디스크나 다른 메모리 장치에서 명명된 파이프로 지원되는 경우 cmd1 > tmpfile; cmd2 < tmpfile
; 그러나 명명된 파이프인 경우 파이프가 가득 차면 출력이 차단될 수 있으므로 백그라운드에서 실행되어야 합니다). 결과가 필요하고 그 출력을 으로 보내야 하는 경우 디스크 읽기가 발생하지 않도록 허용하고 병렬로 실행해야 합니다.tmpfile
cmd1
cmd1
cmd2
cmd1 | tee tmpfile | cmd2
cmd1
cmd2
cmd2
명명된 파이프는 많은 프로세스가 동일한 파이프를 읽고 쓰는 경우 유용합니다. 프로그램이 사용해야 하는 IO에 대해 stdin/stdout을 사용하도록 설계되지 않은 경우에도 유용합니다.문서. 파일을 기울임꼴로 표시한 이유는 명명된 파이프가 메모리에 상주하고 버퍼 크기가 고정되어 있기 때문에 저장소 관점에서 정확히 파일이 아니기 때문입니다.파일 시스템 항목(참고용으로만). 다른물건UNIX에는 파일 대신 파일 시스템 항목이 있습니다. /dev/null
또는 의 다른 항목만 고려하십시오./dev
/proc
명명된 파이프와 명명되지 않은 파이프에는 고정된 버퍼 크기가 있으므로 해당 파이프에 대한 읽기/쓰기 작업이 차단되어 읽기/쓰기 프로세스가 IOWait 상태로 들어갈 수 있습니다. 또한, 메모리 버퍼에서 읽을 때 언제 EOF를 받나요? 이 행동에 관한 규칙은 명확하게 정의되어 있으며 남성에게서도 찾아볼 수 있습니다.
명명된 파이프와 명명되지 않은 파이프로 수행할 수 없는 한 가지는 데이터를 조회하는 것입니다. 메모리 버퍼를 사용하여 구현되므로 이는 이해할 수 있습니다.
에 대해서는 "everything in Linux/Unix is a file"
동의하지 않습니다. 명명된 파이프에는 파일 시스템 항목이 있지만 정확히 파일은 아닙니다. 이름이 없는 파이프에는 파일 시스템 항목이 없습니다( 제외 /proc
). 그러나 UNIX에서 대부분의 IO 작업은 읽기/쓰기 기능을 사용하여 수행됩니다.파일 설명자, 이름 없는 파이프(및 소켓) 포함. 나는 우리가 그렇게 말할 수 있다고 생각하지 않습니다 "everything in Linux/Unix is a file"
. 그러나 우리는 확실히 할 수 있습니다 "most IO in Linux/Unix is done using a file descriptor"
.
답변2
UNIX 철학의 두 가지 기본 원칙은 다음과 같습니다.
- 한 가지 일을 잘 수행하는 작은 프로그램을 만드십시오.
그리고 각 프로그램의 출력이
다른 알려지지 않은 프로그램의 입력이 될 것으로 예상합니다.파이프를 사용하면 이 두 가지 디자인 기반의 효과를 활용하여
매우 강력한 명령 체인을 만들어 원하는 결과를 얻을 수 있습니다.파일에 대해 작동하는 대부분의 명령줄 프로그램은 표준 입력(키보드를 통해 입력)의 입력을 허용하고 표준 출력(
화면에 인쇄)으로 출력할 수도 있습니다.일부 명령은 파이프 내에서만 작동하도록 설계되었으며 파일에 직접 작동할 수 없습니다.
예를 들어
tr
다음 명령은
ls -C | tr 'a-z' 'A-Z'
cmd1 | cmd2
cmd1의 STDOUT을 화면이 아닌 cmd2의 STDIN으로 보냅니다.
STDERR은 파이프를 통해 전달되지 않습니다.
즉,
Pipes is character (|)
명령을 연결할 수 있습니다.STDOUT에 쓰는 모든 명령은 파이프의 왼쪽에서 사용할 수 있습니다.
ls - /etc | less
STDIN에서 읽은 모든 명령은 파이프 오른쪽에서 사용할 수 있습니다.
echo "test print" | lpr
전통적인 파이프는 익명으로 존재하고 프로세스가 실행되는 동안에만 지속된다는 점에서 "이름이 없습니다". 명명된 파이프는 시스템에 영구적이고 프로세스 수명 외부에 존재하며 더 이상 사용되지 않으면 삭제해야 합니다. 프로세스는 일반적으로 명명된 파이프(일반적으로 파일로 표시됨)에 연결되어 IPC(프로세스 간 통신)를 수행합니다.
답변3
다른 답변을 보완하려면 ...
stdin 및 stdout은 파일 설명자이며 파일처럼 읽고 쓸 수 있습니다. 따라서 echo hi | grep hi
echo의 표준 출력을 파이프로 바꾸고 grep의 표준 입력을 해당 파이프의 다른 쪽 끝으로 바꾸는 이렇게 할 수 있습니다 .
답변4
모든 것이 파일입니다.
이 문장을 너무 문자 그대로 받아들이면 "파일만 있고 다른 것은 없습니다"라는 의미로 끝나게 됩니다. 이것은 올바른 설명이 아니므로 무엇입니까?
"모든 것이 파일이다"라고 말할 때 모든 것이 디스크에 저장된다는 의미는 아닙니다. 우리는 모든 것이 파일처럼 보이고, 읽을 수 있고, 쓸 수 있다고 말합니다.
Unix에서는 파일 또는 파일이 아닌 파일을 열면 파일로 처리됩니다. 그러나 모든 작업이 모든 파일에서 지원되는 것은 아닙니다. 예를 들어, 일부 파일(파일 아님)은 검색을 지원하지 않습니다. 해당 파일은 순차적으로 읽고 써야 합니다(파이프와 소켓도 마찬가지).
모든 것에는 파일 이름이 있습니다(일부 시스템에서는: 예를 들어 Debian Gnu/Linux 및 기타 많은 Gnu/Linux).
- 열려 있는 모든 파일에는 파일 이름이 있습니다. 바라보다
/proc/self/fd/…
/dev/tcp
파일 이름 을 사용하여 네트워크 소켓을 열 수 있습니다.cat </dev/tcp/towel.blinkenlights.nl/23