정리가 끝났는지 확인하는 스크립트를 짜면서 특정 접두어로 시작하는 폴더가 남아 있는지를 검사했다. 남아 있으면 잔존으로 없으면 통과로 찍히게 했는데 폴더가 하나도 없는데도 항상 잔존이 나왔다.
Table of contents
Open Table of contents
검색 명령의 종료 코드 규칙
원인은 그 검색 명령이 매치가 0건이어도 성공을 반환한다는 데 있었다. 파일을 못 찾은 것은 검색의 실패가 아니라는 관점이다.
그래서 성공 분기가 항상 실행되고 실패 분기는 절대 실행되지 않았다. 없는 파일을 찾아 종료 코드를 찍어 보면 출력은 없는데 코드가 0으로 나오므로 5초면 확인된다.
명령마다 다른 규칙
이것을 알고 나서 자주 쓰는 것들을 확인했더니 규칙이 제각각이었다. 문자열 검색 명령은 못 찾으면 1을 반환해서 같은 형태의 분기가 의도대로 동작한다.
비교 명령은 반대로 차이가 있을 때 1을 반환하는데 같으면 성공이라는 관점이라 직관과는 맞지만 다른 명령과 섞어 쓰면 헷갈린다. 같은 형태의 분기를 썼는데 명령만 바뀌어도 판정이 뒤집히므로 종료 코드를 쓰기 전에 그 명령의 규칙을 확인해야 한다.
출력 유무로 하는 판정
고친 방식은 출력을 변수에 담아 비어 있는지로 판정하는 것이었다. 종료 코드가 아니라 실제 출력을 본다.
found=$(find "$DIR" -type d -name "_*" 2>/dev/null)
if [ -z "$found" ]; then echo "✓ 0개"; else echo "$found"; fi
남아 있으면 무엇이 남았는지도 함께 찍게 했다. 개수만 세면 무엇이 남았는지 모르고 0건이라는 출력만 보면 안 찾은 것인지 없는 것인지도 모른다.
같은 유형의 다른 사례
같은 성격을 몇 개 더 만났다. 조건이 정확히 일치할 때만 지우는 삭제 API가 조건이 안 맞아도 오류 대신 요청 접수됨을 돌려줘서 지운 줄 알고 넘어간 적이 있었다.
문자열 치환 함수가 대상을 못 찾아도 예외 없이 원본을 그대로 돌려주는 것도 같은 유형이고 그 결과 부분만 반영된 파일이 저장됐다. 컨테이너에 필요한 클라이언트가 없어서 아무것도 안 했는데 빈 결과를 줄 수로 세니 1로 잡혀 대상 한 건으로 진행된 적도 있다. 전부 실패가 아니라는 것과 성공했다는 것을 같게 취급한 경우였다.
대조군을 만드는 확인
그래서 확인 방식에 한 단계를 더 뒀다. 결과가 예상과 같게 나오면 반대 입력으로 한 번 더 돌린다.
통과가 나왔으면 실패해야 하는 입력을 넣어 보고 그때도 통과가 나오면 그 검사는 아무것도 가르지 못한 것이다. 명령이 성공했다는 것과 의도한 상태가 됐다는 것은 다르므로 마지막에는 다시 조회해서 결과를 확인한다.
정리
- 검색 명령은 못 찾아도 성공을 반환할 수 있다
- 그러면 성공과 실패 분기가 항상 한쪽만 탄다
- 문자열 검색과 비교 명령은 규칙이 서로 다르다
- 종료 코드가 아니라 출력 유무로 판정한다
- 무엇이 남았는지를 함께 찍는다
- 아무것도 안 지우고 성공하는 API도 같은 유형이다
- 실패가 아니라는 것과 성공했다는 것은 다르다
- 반대 입력으로 한 번 더 돌려 검사가 실제로 가르는지 확인한다