파이프(Pipe)
- 파이프 ( | ) 기호는 리눅스에서 한 프로세스(process)의 출력을 다른 프로세스의 입력으로 보내는 역할을 한다.
- A | B 의 의미는 다음과 같다: 명령어 A의 출력(stdout)을 명령어 B의 입력(stdin)으로 보낸다.
- 파이프는 효율성을 위해 내부적으로 버퍼(buffer)를 사용한다. 버퍼의 크기는 따로 조사해보지는 않았지만 4KB 정도의 크기인 것 같다. 파이프는 A에서 나오는 출력을 즉시 보내는 것이 아니라 (1) 버퍼가 가득 차거나, (2) 명령어 A의 수행이 완료될 때, B로 전달한다.
문제 상황
- 시뮬레이션의 계산 결과를 stdout과 파일에 동시에 출력하고 싶었다. 따라서 tee 명령을 사용했다.
- 예) python3 sim.py | tee output.txt
- 출력 버퍼를 채우는 데 매우 오랜 시간이 걸려서 화면 & 파일에 아무것도 뜨지 않는다. I/O 효율성은 아무래도 상관없으니 실시간으로 결과를 확인하고 싶다.
해결 방법1: 명시적으로 flush 호출하기
- 적당한 시점에 sys.stdout.flush() 를 넣으면 된다.
import sys
print("...")
sys.stdout.flush() # print 다음에
해결 방법2: unbuffer 명령 사용
- `expect` 패키지와 함께 딸려온 unbuffer 명령을 쓰면 stdout 버퍼를 사용하지 않을 수 있다.
- 예) unbuffer python3 sim.py | tee output.txt
설치 (Ubuntu)
- sudo apt install expect
- 맥에서는 확인해보지 않았는데 brew를 통해 설치할 수 있는 것 같다.