728x90
표준 입출력(stdin/stdout)과 파이프 활용
쉘 스크립트에서 표준입력, 출력, 에러를 대충 넘기는 경우가 많지만, 이를 정확히 이해하면 실무에서 디스크 공간과 처리 속도를 크게 개선할 수 있다.
기본 개념
표준 스트림의 종류
stdin (Standard Input, 표준입력)
- 프로그램이 데이터를 입력받는 기본 통로
- 기본값: 키보드 입력
stdout (Standard Output, 표준출력)
- 프로그램이 결과를 출력하는 기본 통로
- 기본값: 터미널 화면
stderr (Standard Error, 표준에러)
- 에러 메시지 출력 전용 통로
파이프(|)의 동작 원리
파이프는 앞 명령의 stdout을 뒤 명령의 stdin으로 자동 연결한다.
command1 | command2
↓ ↑
stdout → stdin
파이프 예시
$ echo hello world | cat foo.txt - bar.txt
111
222
hello world
333
444
동작 순서
- echo hello world가 "hello world"를 stdout으로 출력
- 파이프(|)가 이를 cat의 stdin으로 전달
- cat이 순서대로 출력
- foo.txt 파일 내용 출력 (111, 222)
- stdout(-)위치에서 stdin 내용 출력 (hello world)
- bar.txt 파일 내용 출력 (333, 444)
` - ` 기호의 의미
많은 Unix/Linux 명령어에서 -는 "파일 대신 stdin/stdout을 사용하라"는 특수 기호다.
기본 사용법
# 파일 대신 stdout으로 출력
tar -cf - dir/ # tar 결과를 stdout으로
wget -O - URL # 다운로드를 stdout으로
# 파일 대신 stdin에서 입력
cat file1 - file2 # file1, stdin, file2 순서로 출력
diff - local.txt # stdin과 local.txt 비교
동작 원리 상세 설명
# 1단계: tar의 올바른 형식
tar -cf [생성할파일명] [압축할대상]
# 2단계: - 사용
tar -cf - dir/
- tar -cf의 올바른 형식은 tar -cf [생성할파일명] [압축할대상]이다.
- tar -cf - dir/에서 - 는 생성할 파일명 위치에 있다.
- 따라서 파일로 저장하지 않고 stdout(표준출력)으로 출력, 즉 스트림(바이너리) 로 출력된다.
- 결과: 터미널에 엄청난 압축 파일의 바이너리 형식 데이터들이 쏟아져 나온다.
이것만 보면 "왜 이걸 사용하는가?"라는 의문이 든다. 답은 실무에서 어떻게 활용하는지 보면 이해가 된다.
실무 활용 예시
1. 중간 파일 없이 네트워크 전송
예를 들어 어떤 파일을 압축해서 보내야 하는데, 디스크 용량마저도 부족한 경우가 있다.
그런 경우에 이 방법을 사용하는 경우가 있다.
# 1번 예시 (나쁜 방법)
# (2단계, 디스크 2배 사용)
tar -czf backup.tar.gz /data/
scp backup.tar.gz server:/backup/
# 2번 예시 (좋은 방법)
# (스트림 전송, 디스크 절약)
tar -czf - /data/ | ssh server "cat > /backup/backup.tar.gz"
2번 예시의 처리 순서는 아래와 같다.
- tar가 /data/ 읽음
- gzip으로 압축한 내용을 바이너리 스트림으로 생성
- stdout으로 바이너리 스트림 출력
- 파이프(메모리)로 ssh에 전달
- ssh가 바이너리를 그대로 네트워크로 전송
- 서버에서 바이너리 그대로 파일로 저장
※ 스트림: 데이터 흐름 자체를 의미하고 바이너리/텍스트 중 어떤 걸로 보낼지 지정할 수 있다.
두 가지 예시의 차이점
# 1번: 디스크 사용
/data/ (100GB)
→ tar -czf 실행
→ backup.tar.gz 생성 (30GB) ← 디스크 사용!
→ scp로 읽어서 전송
총 디스크 사용: 100GB + 30GB = 130GB
# 2번: 디스크 절약
/data/ (100GB)
→ tar -czf - 실행
→ 압축 데이터를 메모리에서 바로 ssh로 전달
→ 서버에서 저장
총 디스크 사용: 100GB (원본만)
2. 원격 파일 비교
# 로컬 파일과 원격 파일을 직접 비교
ssh server "cat /etc/nginx/nginx.conf" | diff - /etc/nginx/nginx.conf
설명: ssh를 이용해 server의 /etc/nginx/nginx.conf 설정파일을 로컬 /etc/nginx/nginx.conf 파일과 비교한다고 이해하면 된다.
3. 데이터 가공 파이프라인
# 압축 → 암호화 → 전송 (중간 파일 저장 없음)
tar -czf - /data/ | openssl enc -aes-256-cbc | ssh server "cat > encrypted.tar.gz.enc"
설명: 파일을 별도로 생성하지 않고 파이프(메모리)에서 처리해 스트림으로 전송한다.
핵심 장점
- 디스크 공간 절약: 중간 파일을 만들지 않음
- 속도 향상: 파일 I/O 없이 메모리/네트워크로 직접 전달
- 파이프라인 구성: 여러 명령을 효율적으로 연결
- 실시간 처리: 스트림 방식으로 데이터 처리
리다이렉션 기호 정리
> # stdout을 파일로 (덮어쓰기)
>> # stdout을 파일로 (추가)
< # 파일에서 stdin으로
2> # stderr을 파일로
| # stdout을 다음 명령의 stdin으로
- # 파일 대신 stdin/stdout 사용
728x90