Rust CLI 출력

stdout과 stderr 분리

CLI 프로그램은 화면에 보이는 문자열보다 출력 채널과 종료 코드가 중요하다. 정상 데이터는 stdout, 진단 메시지는 stderr, 실패 여부는 exit code로 분리해야 조합 가능한 도구가 된다.

01

결과 출력

파이프나 리다이렉션 대상이 되는 데이터는 println! 또는 stdout writer로 보낸다.

기계가 읽는 값
02

진단 출력

진행률, 경고, 에러 설명은 eprintln!으로 stderr에 보낸다.

데이터 오염 방지
03

오류 전파

main에서 Result를 반환하거나 process::exit로 종료 코드를 명확히 한다.

스크립트 판단 근거
04

테스트

assert_cmd로 stdout, stderr, code를 따로 검증한다.

계약 단위 테스트
pipe
stdout만 다음 명령으로 전달 검색 결과나 JSON 출력은 stderr 로그와 섞이면 파싱이 깨진다.
진단은 stderr
redirect
파일 저장 채널 선택 >는 stdout, 2>는 stderr를 저장하므로 문제 재현에 도움이 된다.
운영 로그 분리
exit code
자동화 성공 여부 문자열 메시지보다 종료 코드가 CI와 shell 스크립트의 판단 기준이다.
0만 성공
flush
버퍼링 영향 긴 작업이나 progress 출력은 writer flush 또는 로그 채널 정책을 확인한다.
순서 착각

JSON 출력 · 테스트 실패 · 라이브러리화 점검

JSON 출력 stdout에 JSON을 내보내는 도구는 stderr에만 사람이 읽는 오류 설명을 둔다.
테스트 실패 문구만 assert하지 말고 실패 코드와 채널까지 함께 확인한다.
라이브러리화 비즈니스 로직은 writer를 주입받게 만들면 stdout/stderr 테스트가 쉬워진다.

assert_cmd 관점

cmd.assert()
  .failure()
  .stderr(predicate::str::contains("not found"))
  .stdout(predicate::str::is_empty());