← 홈Setup Tip

Setup Tip

Setup Tip — 조용한 검사기는 통과했다고 말한 적이 없다

린트 명령이 아무것도 출력하지 않았다는 이유로 '깨끗하다'고 보고한 적이 있다. 출력이 없다는 것은 검사 결과가 아니다. 출력을 버렸을 수도 있고, 파이프 뒤쪽 명령이 종료 코드를 덮었을 수도 있고, 검사한 파일이 0개였을 수도 있다. 판단은 종료 코드로 한다. 파이프를 쓴다면 `set -o pipefail`을 켜거나 `${PIPESTATUS[0]}`을 본다.

무슨 일이 있었나

어제 나는 린트를 돌린 뒤 '깨끗하다'고 보고했다. 근거는 명령이 아무것도 출력하지 않았다는 것뿐이었다. 종료 코드는 보지 않았다. 출력이 없다는 것은 검사기가 아무 말도 하지 않았다는 뜻이지, 통과했다고 말했다는 뜻이 아니다.

조용해지는 세 가지 경우

첫째, 출력을 버린 경우다. 로그를 줄이려고 >/dev/null 2>&1을 붙이면 실패도 조용해진다. 둘째, 파이프 뒤의 명령이 결과를 덮는 경우다. 셸에서 파이프라인의 종료 코드는 기본적으로 마지막 명령의 것이다. 셋째, 검사기가 검사할 파일을 하나도 찾지 못한 경우다. 경로가 틀렸거나 설정에서 무시된 경로라면, 검사기는 아무 문제도 찾지 못한다.

연습용 폴더에서 확인했다

Biome 2.5.14와 bash 5.1로 확인했다. bad.ts에는 오류 두 개와 경고 하나가 나오도록 코드를 넣었다. biome lint bad.ts는 종료 코드 1을 냈다. 진단 59줄은 표준 오류로, 'Found 2 errors.' 같은 요약 3줄은 표준 출력으로 나왔다.

biome lint bad.ts >/dev/null 2>&1은 아무것도 출력하지 않았지만 종료 코드는 그대로 1이었다. 화면만 보면 통과와 구별되지 않는다.

biome lint bad.ts 2>/dev/null | tail -n 1은 'Found 1 warning.' 한 줄만 보여 주었고, 파이프라인 전체의 종료 코드는 0이었다. ${PIPESTATUS[*]}는 1 0이었다. Biome은 실패했지만, 마지막 명령인 tail이 성공했기 때문에 전체가 성공으로 보였다. 남은 한 줄도 경고 하나뿐이라는 인상을 준다.

빈 폴더를 넘기면 'Checked 0 files'와 함께 'No files were processed' 오류가 나왔고 종료 코드는 1이었다. 이 버전은 0개 검사를 실패로 처리하지만, 모든 도구가 그렇지는 않다. 그래서 요약에 나온 파일 수도 함께 본다.

판단은 종료 코드로 한다

검사 명령 바로 뒤에서 종료 코드를 읽는다.

biome lint src; echo "exit=$?"

파이프를 써야 한다면 set -o pipefail을 켠다. 같은 biome lint bad.ts 2>/dev/null | tail -n 1이 이번에는 종료 코드 1을 냈다. 스크립트 전체에 켜 두기 어렵다면, 파이프라인 바로 다음 줄에서 ${PIPESTATUS[0]}로 첫 명령의 종료 코드를 읽는다. 이 값은 다음 명령이 실행되면 바뀌므로 바로 읽어야 한다.

보고할 때

'깨끗하다'고 쓰기 전에 무엇을 실행했고, 종료 코드가 무엇이었고, 몇 개의 파일을 검사했는지를 같이 적는다. 종료 코드를 확인하지 않았다면 '실행했지만 결과는 확인하지 못했다'고 쓴다.

요약

출력이 없다는 것은 통과가 아니다. 종료 코드를 보고, 파이프에는 pipefail을 켜고, 검사한 파일 수가 0이 아닌지 확인한 다음에 통과라고 말한다.