로그인 회원가입
모두인포
전체IT경제사회생활스포츠시사여행연애

Linux I/O Redirection

lmkfox · 2025-10-04 · 조회 0
Linux I/O Redirection
1. 기본 개념 (파일 디스크립터) - FD 0 : stdin - FD 1 : stdout - FD 2 : stderr 명령 → stdout/stderr로 결과를 출력. 리다이렉션으로 이들을 파일이나 파이프로 보냄. 2. 기본 리다이렉션 문법 # stdout을 파일로 (덮어쓰기) command > out.txt # stdout을 파일에 추가(append) command >> out.txt # stderr을 파일로 command 2> err.txt # stderr을 파일에 추가 command 2>> err.txt # stdin을 파일로부터 읽기 command < input.txt 3. stdout/stderr 합치기 (merge) — 순서 주의 # stdout과 stderr를 같은 파일로 합치기 (포터블) command > out_and_err.txt 2>&1 # 또는 (bash 전용 간단문법) command &> out_and_err.txt 중요 — 순서가 중요 - command > out 2>&1 : >가 먼저 수행되어 stdout이 파일로 향하고, 그 다음 2>&1로 stderr를 현재(바뀐) stdout으로 복제 → stderr도 파일로 들어감. (의도한 동작) - command 2>&1 > out : 먼저 stderr를 현재 stdout(터미널)으로 복제, 그 다음 stdout을 파일로 변경 → stderr는 여전히 터미널로 남음. 즉 서로 다른 결과. 항상 > file 2>&1 또는 2>file 1>&2 등 의도한 순서로 작성할 것. 4. stderr만 리다이렉트 / stdout만 콘솔 유지 # stdout은 그대로 콘솔에, stderr만 파일로 command 2> err.txt # stdout을 파일로, stderr는 콘솔에 유지 (순서 중요) command 2> /dev/tty > out.txt # 복잡하므로 보통 아래 방식 권장 # 추천: stdout만 파일, stderr는 터미널로 남겨두려면 command > out.txt # stderr 자동으로 콘솔에 남음 # (하지만 > out.txt 2>&1 would combine) 5. /dev/null 사용 — 출력 무시 # 표준출력 무시 command > /dev/null # 표준에러 무시 command 2> /dev/null # 둘 다 무시 command > /dev/null 2>&1 # 또는 bash: command &> /dev/null 6. 파이프와 tee - 파이프 |는 한 명령의 stdout을 다음 명령의 stdin으로 보냄(주로 stdout만 전달 — stderr는 전달되지 않음). cmd1 | cmd2 - tee는 stdout을 파일로 쓰면서 다음 프로세스로도 전달: cmd | tee logfile | other_cmd # 출력 기록 + 파이프 계속 # 로그 파일에만 쓰려면: cmd | tee logfile > /dev/null 7. Here-documents / Here-strings - Here-document: 여러 줄을 표준입력으로 제공 cat <<EOF > file.txt line1 line2 $VARIABLE # 변수 확장됨 EOF - 변수 치환을 막고 싶으면 'EOF'로 감싸기: cat <<'EOF' $VARIABLE # 그대로 출력 EOF - <<-EOF는 각 줄의 선행 탭을 제거(탭으로 들여쓰기된 스크립트에서 유용). - Here-string (bash/ksh): grep pattern <<< "$variable" 8. 프로세스 치환 (process substitution) —  <(...) ,  >(...)  (bash, zsh) - 명령의 출력을 파일처럼 취급(임시 FIFO 사용): # diff 두 정렬된 파일 비교 diff <(sort fileA) <(sort fileB) # 명령의 결과를 프로그램의 파일 인자로 전달 some_cmd >(process_output) 유용: 명령 간 비교·병렬 처리 시. 9. 여러 명령 블록 리다이렉션 - 여러 명령을 하나의 파일로 리다이렉트하려면 brace {} 또는 subshell () 사용: # 같은 셸에서 리다이렉트 (중괄호, 세미콜론 필요) { cmd1; cmd2; } > all_out.txt 2>&1 # 서브셸(별도 프로세스) ( cmd1; cmd2 ) > all_out.txt 2>&1 중괄호는 현재 셸에서 실행되며 } 앞에 공백 필요. 10. exec로 파일 디스크립터 조작 (현재 셸에 영향) - 스크립트 전체의 출력을 로그 파일로 보내려면: exec > script.log 2>&1 # 이후 이 셸에서 실행되는 모든 명령의 stdout/stderr가 script.log로 감. - 원래 stdout 저장하고 복원: exec 3>&1 # FD 3에 원래 stdout 저장 exec > out.txt # stdout을 파일로 바꿈 # ... 작업 ... exec >&3 3>&- # stdout 복원, FD 3 닫기 FD 숫자(3,4 등)는 임의로 사용 가능(0..2는 표준). - FD 닫기: exec 3>&- # FD 3 닫음 11. 고급: 파일 디스크립터 복제 / 복원 예제 # 현재 stdout을 FD 3에 저장 exec 3>&1 # stdout을 파일로 리다이렉트 exec 1>out.log # 이 시점에서 명령들 echo "this goes to out.log" # 잠깐 원래 stdout(터미널)에 쓰기 echo "to terminal" >&3 # 복원 exec 1>&3 3>&- 12. sudo와 리다이렉션 문제 sudo는 리다이렉션 자체는 셸(사용자 권한)에서 처리하기 때문에 sudo로 명령만 root로 실행해도 > /root/file 같은 리다이렉션은 권한 부족 에러가 날 수 있습니다. 해결법: # 1) sudo sh -c 'command > /root/file' sudo sh -c 'echo hello > /root/somefile' # 2) 또는 tee 사용 echo hello | sudo tee /root/somefile > /dev/null 13. 두 출력( stdout/stderr )을 서로 다른 파일로 저장 command > out.txt 2> err.txt 혹은 시간 순서를 보존하려면 stdbuf나 unbuffer로 버퍼링 조정(파이프를 통해 순서가 섞일 수 있음). 14. 리다이렉션 관련 흔한 실수와 해결 - 순서 실수: command 2>&1 > out 은 의도대로 작동하지 않음(위 참조). - 권한 문제: sudo로 실행해도 >는 여전히 비루트 셸에서 수행 → sudo sh -c 또는 tee 사용. - 버퍼링으로 인한 출력 순서 변경: 파이프나 파일로 리다이렉션하면 stdout/stderr 버퍼링이 달라져 출력 순서가 바뀔 수 있음. stdbuf -oL 등으로 라인 버퍼링을 강제하거나 unbuffer 사용. - &>는 bash 전용: POSIX 호환성을 원하면 >file 2>&1 사용. 15. 로그·디버깅 실무 예제 - 스크립트 전체를 로그로 남기기: #!/bin/bash exec > >(tee -a /var/log/myscript.log) 2>&1 # 이렇게 하면 stdout은 파일과 터미널에 동시에 쓰임, stderr도 합쳐서 둘 다로 echo "start" # rest of script - 안전한 백그라운드 실행(로그 보존): nohup myscript.sh > /var/log/myscript.out 2>&1 & 16. named pipe (FIFO) 와 리다이렉션 - mkfifo /tmp/myfifo로 FIFO 생성 후 producer/consumer를 연결 가능: mkfifo /tmp/f # in one shell: cat /tmp/f | process_consumer # in another shell: echo "data" > /tmp/f 17. Quick reference (요약) - > : stdout → 파일(덮어쓰기) - >> : stdout → 파일(추가) - < : stdin ← 파일 - 2> : stderr → 파일 - &> : stdout+stderr → 파일 (bash 전용) - >file 2>&1 : stdout → file, stderr → same as stdout (포터블) - command | command : stdout 파이프 전달 - cmd | tee file : stdout을 file과 파이프 둘 다로 - <<EOF : here-document (여러 줄 stdin) - <(cmd) : process substitution (파일처럼 사용)

댓글

아직 댓글이 없습니다.

로그인 후 댓글을 남길 수 있습니다.