파이프를 이해하는 방법


21

bash에서 파이프를 사용했을 때 이것에 대해 더 많이 생각하지 않았습니다. 그러나 fork ()와 함께 시스템 호출 pipe ()를 사용하여 C 코드 예제를 읽을 때 익명 파이프와 명명 된 파이프를 포함하여 파이프를 이해하는 방법이 궁금합니다.

"리눅스 / 유닉스의 모든 것은 파일이다"라는 말이 종종 들린다. 파이프가 실제로 파일인지 확인하여 연결하는 한 부분이 파이프 파일에 쓰고 다른 부분은 파이프 파일에서 읽습니다. 그렇다면 익명 파이프의 파이프 파일은 어디에 생성됩니까? / tmp, / dev 또는 ...?

그러나 명명 된 파이프의 예에서 파이프를 사용하면 임시 파일을 명시 적으로 사용하는 것보다 공간 및 시간 성능 이점이 있음을 알았습니다. 파이프 구현에 관련된 파일이 없기 때문일 수 있습니다. 또한 파이프는 파일처럼 데이터를 저장하지 않는 것 같습니다. 파이프가 실제로 파일인지 의심합니다.

답변:


23

성능 질문에 대해서는 디스크 IO가 필요하지 않기 때문에 파이프가 파일보다 효율적입니다. 그래서 cmd1 | cmd2보다 효율적입니다 cmd1 > tmpfile; cmd2 < tmpfile(이 힘이있는 경우에 true를하지 tmpfileRAM 디스크 또는 명명 된 파이프 같은 다른 메모리 장치에 백업되어 있지만 명명 된 파이프의 경우, cmd1파이프가 가득 차면 출력이 방해가 될 수 있으므로 백그라운드에서 실행되어야한다 ). 당신의 결과가 필요한 경우 cmd1여전히 그 출력을 보낼 필요가 cmd2, 당신은해야 cmd1 | tee tmpfile | cmd2허용 할 cmd1cmd2디스크에서 읽기 작업을 피하는 병렬로 실행 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".


감사! 첫 번째 작업이 완료된 후 두 번째 명령이 실행되는 대신 두 개의 명령이 병렬로 실행되는 파이프로 연결되어 있습니까?
Tim

예, 2 개의 명령이 병렬로 실행됩니다. 버퍼가 아닌 첫 번째 출력보다 많으면 차단됩니다. 당신은 실행하여 시도 할 수 있습니다 cmd1 > fifocmd2 < fifo함께 명명 된 파이프를 생성, 2 개의 다른 조개에 mkfifo fifo.
jfg956

당신이 할 수있는 또 다른 테스트 는 여전히 실행중인 cmd2동안 죽이는 것입니다 cmd1: cmd1아마도 깨진 파이프 메시지를보고하지 않을 것입니다.
jfg956

감사! 무슨 뜻인가요? 이 경우 차단 후 스트림의 날짜가 손실된다는 의미입니까?
Tim

2
데이터가 손실되지 않습니다. 파이프 버퍼가 가득 찬 경우 파이프 cmd1에 대한 쓰기는 파이프 cmd2에서 데이터를 읽었을 때만 반환됩니다 . 같은 방식 cmd2으로 파이프에 대한 읽기는 파이프에 cmd1쓸 때까지 버퍼가 비어 있으면 차단됩니다 .
jfg956

4

유닉스 철학의 기본 원칙 중 두 가지는

  1. 한 가지 일을 잘하는 작은 프로그램을 만들기 위해.
  2. 모든 프로그램의 출력이
    아직 알려지지 않은 다른 프로그램의 입력이 될 것으로 기대합니다 .

    파이프를 사용하면이 두 가지
    기본 설계의 효과를 활용 하여 원하는 결과를 얻을 수있는 매우 강력한 명령 체인을 만들 수 있습니다.

    파일에서 작동하는 대부분의 명령 줄 프로그램은 표준 입력 (키보드를 통한 입력) 및 표준 출력 (
    화면 인쇄)으로 입력을받을 수도 있습니다 .

    일부 명령은 파이프 내에서만 작동하도록 설계되어 파일에서 직접 작동 할 수 없습니다.

    예를 들어 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)을 수행하기 위해 명명 된 파이프 (일반적으로 파일로 표시됨)에 연결됩니다.

출처 : http://en.wikipedia.org/wiki/Named_pipe


3

다른 답변을 보완하려면 ...

stdin 및 stdout은 파일 설명자이며 마치 파일 인 것처럼 읽고 씁니다. 따라서 할 수 있으며 echo hi | grep hiecho의 stdout을 파이프로 바꾸고 grep의 stdin 을이 파이프의 다른 쪽 끝으로 바꿉니다.


1

모든 것이 파일입니다.

문구를 너무 문자 그대로 받아들이면 "파일 만 있고 다른 것은 없습니다"라는 의미로 끝납니다. 이것은 올바른 해석이 아니므로 무엇입니까?

“모든 것이 파일입니다”라고 말할 때 모든 것이 디스크에 저장되어 있다고 말하는 것은 아닙니다. 우리는 모든 것이 파일처럼 보이고, 읽고, 쓸 수 있다고 말합니다.

유닉스에서는 파일 또는 파일이 아닌 파일이 열리면 파일처럼 취급 될 수 있습니다. 그러나 모든 파일이 모든 작업을 지원하는 것은 아닙니다. 예를 들어 파일이 아닌 일부 파일은 검색을 지원하지 않습니다. 파일을 순서대로 읽거나 써야합니다 (파이프 및 소켓에 해당).

모든 파일 이름은 데비안 GNU / 리눅스 및 기타 Gnu / 리눅스와 같은 일부 시스템에서 사용됩니다.

  • 열려있는 모든 파일은 파일 이름을 갖습니다. 만나다/proc/self/fd/…
  • 네트워크 소켓은 파일 이름 참조 열 수 있습니다 /dev/tcp
    예를 들어,cat </dev/tcp/towel.blinkenlights.nl/23

마지막 부분은 /proc파일 시스템이있는 시스템과 /dev/tcp파일 구조 를 제공하는 시스템 (또는 쉘) 에서만 유효합니다 .
Kusalananda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.