인용과 표준 입출력
60분 안팎
학습 목표
파이프·인용·표준 오류·종료 코드를 적용해 실습 파일 목록을 기록합니다.
개념
출력은 한 종류가 아닙니다
운영 점검에서 결과 파일이 비었다는 이유만으로 성공이라고 판단하면 오류를 놓칠 수 있습니다. 명령에는 표준 입력, 표준 출력, 표준 오류라는 통로와 종료 코드라는 별도 신호가 있습니다. 이번에는 설정의 ready 행을 찾고 검색 결과, 오류 설명, 판정 값을 각기 남깁니다. 같은 검색에서 일치, 빈 파일, 파일 없음의 세 상황을 비교해 실패 기록을 읽는 연습을 합니다.
표준 입력은 명령이 읽는 데이터 통로이고 표준 출력은 주된 결과를 내보내는 통로입니다. 표준 오류는 진단 메시지를 전달합니다. 셸의 파일 디스크립터 0, 1, 2가 각각 이 통로를 가리킵니다. 명령이 모든 진단을 표준 오류에 쓰는지는 구현에 달렸지만 grep의 파일 읽기 오류는 표준 오류로 관찰할 수 있습니다. 숫자 2를 결과 건수로 착각하지 않고 통로 번호로 읽습니다.
종료 코드는 출력 문자열이 아니라 명령 실행이 끝날 때 셸에 전달하는 상태입니다. 0은 보통 성공을 뜻하고 다른 값의 의미는 명령 규약을 봅니다. grep은 찾은 행이 있으면 0, 일치가 없으면 1, 오류에서는 2를 사용합니다. 검색어가 없다는 정상적인 관측도 1일 수 있어 모든 비zero를 장비 장애라고 표시하면 잘못된 알림이 생깁니다.
인용은 데이터와 문법을 구분합니다
작은따옴표는 셸 변수 치환을 막아 고정 문자열을 그대로 전달하기 좋습니다. 큰따옴표는 변수를 치환하면서 인자 분리를 막습니다. printf의 형식 문자열은 고정하고 변수 값을 별도 인자로 넘기면 % 문자가 데이터에 있어도 형식으로 재해석하지 않습니다. 사용자 문자열을 그대로 printf의 첫 인자로 사용하는 습관은 의도하지 않은 형식 해석을 만들 수 있습니다.
검색어에 점이 들어 있으면 정규식의 점과 문자 그대로의 점을 구분해야 합니다. 버전이나 설정 문자열을 찾을 때는 grep -F로 고정 문자열을 검색합니다. 정규식이 필요한 상황에서는 그 규칙을 별도로 정합니다. 이번 실습의 ready는 고정 문자열 포함 검색이며 줄 전체가 정확히 ready여야 한다는 검사와 다릅니다. 요구사항과 옵션을 맞춰야 테스트가 무엇을 보장하는지 설명할 수 있습니다.
따옴표 밖의 |와 >는 셸 문법입니다. 따옴표 안에 넣으면 보통 글자 데이터로 전달되어 파이프나 리다이렉션이 되지 않습니다. 반대로 파일 내용에 쓰려던 기호를 따옴표 없이 적으면 명령 흐름을 바꿀 수 있습니다. 코드 블록의 기호와 따옴표를 함께 읽고, 셸이 해석할 문법과 명령이 받을 인자가 무엇인지 먼저 나눕니다.
리다이렉션 순서와 보존을 이해합니다
grep 명령 뒤의 > stdout.txt는 표준 출력을 파일로 연결하고 2> stderr.txt는 표준 오류를 별도 파일로 연결합니다. 일치하지 않으면 두 파일이 모두 비어 있을 수 있습니다. 파일이 없으면 표준 출력은 비어도 표준 오류에 경로를 포함한 진단이 남습니다. 결과와 오류를 합치지 않으면 오류 문구를 정상 결과처럼 집계하는 일을 줄일 수 있습니다.
>는 기존 파일을 먼저 비우고 >>는 뒤에 추가합니다. 이번 검사는 매 실행의 결과를 한 세트로 비교하므로 새 결과로 덮어씁니다. 누적 기록을 유지하려면 실행별 파일이나 타임스탬프를 설계해야 합니다. 오류 파일을 한 번 만든 뒤 다음 성공에서 갱신하지 않으면 이전 오류가 현재 오류처럼 보일 수 있습니다. 성공에서도 빈 stderr 파일을 생성해 현재 실행의 상태가 드러나게 합니다.
2>&1은 표준 오류를 그 시점의 표준 출력 대상으로 연결합니다. cmd > all.txt 2>&1은 둘을 파일에 모으지만 cmd 2>&1 > result.txt는 표준 오류가 원래 출력 쪽에 남을 수 있습니다. 셸은 왼쪽에서 오른쪽으로 연결을 바꿉니다. 이번 산출물은 채널 분리가 요구사항이므로 두 파일을 명시합니다. 단순히 화면이 조용해졌다는 관찰만으로 저장 성공을 판단하지 않습니다.
종료 코드를 바로 붙잡습니다
$?는 직전 명령의 종료 코드입니다. grep 뒤에 echo나 mkdir를 실행하고 나서 값을 읽으면 grep의 코드가 아니라 그 명령의 코드를 얻습니다. rc=$?를 검색 직후 실행하고 printf로 status.txt에 저장한 다음 exit "$rc"로 반환합니다. 이렇게 하면 호출자는 반환 상태로 분기하고 담당자는 파일을 열어 같은 판정 값을 확인할 수 있습니다.
set -e는 모든 실패 처리 요구를 대신하지 않습니다. 이 예제는 grep의 1과 2를 파일에 남겨야 하므로 task.sh에서 곧바로 종료시키는 방식이 맞지 않습니다. 검사기에서는 bash task.sh를 조건부로 호출하여 실패 코드를 받습니다. 실패를 || true로 지워 버리면 저장해야 할 판정도 사라질 수 있습니다. 예상한 실패를 잡아 기록하고 실제 실패를 호출자에게 반환하는 목적을 유지합니다.
파이프는 왼쪽 표준 출력을 오른쪽 표준 입력으로 전달합니다. 기본 Bash에서는 파이프 전체의 종료 상태가 마지막 명령의 상태입니다. false | cat이 0으로 끝날 수 있는 이유는 cat이 읽기를 정상 종료했기 때문입니다. set -o pipefail을 켜면 앞쪽 실패도 파이프 상태에 반영됩니다. 그렇더라도 일치 없음과 오류를 업무 규칙으로 분류하는 작업은 별도로 필요합니다.
세 상황을 같은 기준으로 판정합니다
일치 사례의 파일에는 ready, blocked, ready 세 줄이 있습니다. grep -n -F는 1:ready와 3:ready를 결과에 남기고 상태는 0입니다. 빈 파일에서는 출력과 오류가 모두 비고 상태는 1입니다. 파일 없음에서는 결과가 비며 오류 파일에 메시지가 있고 상태는 2입니다. 이 구분은 점검 화면의 빨간색 표시보다 구체적인 근거를 제공하며 후속 자동화의 입력이 됩니다.
No such file or directory를 읽을 때는 메시지가 가리킨 설정 경로를 확인합니다. 출력 파일 생성 실패라면 검색 자체가 실행되지 않았을 수도 있습니다. 이번 task.sh는 evidence 디렉터리를 먼저 준비하여 출력 목적의 누락을 줄입니다. grep 오류 문구 전체는 운영체제와 언어 설정에 따라 달라질 수 있으므로 검사기는 특정 영어 문장 대신 오류 파일이 비어 있지 않은지 확인합니다.
파이프 결과를 wc -l로 세면 공백이 붙어 표시될 수 있습니다. 따라하기는 tr로 표시용 공백을 제거하여 실제 출력과 설명의 형식을 맞춥니다. 파일명의 줄바꿈을 다루는 일반 목록 도구를 이 단순 행 집계로 대체할 수는 없습니다. 이번 입력은 레슨이 만든 짧은 텍스트이며 자료 범위를 제한해 통로와 상태 차이를 관찰합니다.
기록을 읽는 순서가 생깁니다
완료 후에는 status.txt, stderr.txt, stdout.txt를 함께 읽습니다. 상태가 1이면 검색 규칙과 입력 내용부터 확인하고, 2이면 경로와 읽기 오류를 봅니다. 결과가 있어도 상태가 실패인 도구가 있을 수 있으므로 출력 존재만으로 성공을 결정하지 않습니다. 더 읽기의 grep 장에서 검색 옵션을 확장하되 이번 산출물은 세 채널을 보존하는 작은 점검 계약으로 유지합니다.
따라하기
인용 비교
큰따옴표의 변수 치환과 작은따옴표의 고정 문자열을 비교합니다. 새 Bash 환경에서 실행합니다.
label="lab web"
printf "expanded=%s
" "$label"
printf "literal=%s
" '$label'실행 결과
expanded=lab web literal=$label
일치 없음 기록
작은 파일을 만든 뒤 검색 상태를 즉시 보존합니다. 두 통로가 모두 비어도 종료 상태를 별도로 읽을 수 있습니다.
printf "blocked
" > app.conf
grep -n -F ready app.conf > stdout.txt 2> stderr.txt
rc=$?
printf "status=%s
" "$rc"
printf "stdout_bytes=%s
" "$(wc -c < stdout.txt | tr -d ' ')"
printf "stderr_bytes=%s
" "$(wc -c < stderr.txt | tr -d ' ')"실행 결과
status=1 stdout_bytes=0 stderr_bytes=0
파이프 기본 상태 비교
두 실행은 같은 입력을 사용합니다. pipefail은 이 Bash 실행 범위에서만 변경합니다.
set +o pipefail
false | cat
printf "default=%s
" "$?"
set -o pipefail
false | cat
printf "pipefail=%s
" "$?"실행 결과
default=0 pipefail=1
일치 행 집계
표준 출력만 파이프로 보냅니다. 정렬이나 행 수를 서비스 상태 전체로 해석하지 않습니다.
printf "ready
blocked
ready
" | grep -F ready | wc -l | tr -d ' '실행 결과
2
확인 문제
실습
task.sh에서 검색 출력·오류·상태를 각 파일로 남기고 검색 상태를 반환합니다. 일치·빈 파일·파일 없음의 세 상황을 처리합니다.
실행 명령
bash check.sh
기대 결과
PASS io: match, empty, missing
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- 점검 스크립트가 실패를 알리는 방식을 설명합니다.