Skip to content
isdnetworks
Go back

같은 블록 안의 확인은 확인이 아니다

다른 작업 디렉터리에 인계 문서를 쓰다가 같은 이름의 기존 문서를 덮어썼다. 그 안에는 두 건의 판단을 보류하라는 지시가 있었는데 못 본 채로 대상 파일 두 개를 지웠다. 덮기 전에 대상의 현재 상태를 잡는다는 규칙을 며칠 전에 내가 적었는데도 그렇게 됐다.

Table of contents

Open Table of contents

볼 수 없는 순서

명령을 이렇게 짰다.

ls "$C" | grep handoff
cat > "$C/handoff.md" <<'EOF'
...
EOF

확인하고 나서 쓰는 순서이므로 언뜻 맞는 것처럼 보인다. 문제는 확인과 쓰기가 같은 블록 안에 들어 있다는 점이다. 이 블록은 통째로 실행되고 그 결과는 모든 명령이 끝난 뒤에 한 번에 출력된다.

목록이 화면에 보이는 시점에는 그 아래의 쓰기도 이미 끝나 있는 상태다. 기존 파일 이름이 목록에 있는 것을 봤을 때는 그 파일이 이미 없어진 뒤다. 판단할 틈이 구조적으로 없었고 규칙은 문면으로 지켜지면서 실행 패턴에서 무력화됐다.

근거를 지운 뒤의 집계

이 구조를 알고 나니 비슷한 것이 보였다. 실패 기록을 가진 대상을 전수 조회했더니 0건이 나왔고 조건을 바꿔 다시 돌려도 여전히 0건이었다.

직전에 그 실패 기록을 초기화한 것이 나였다는 사실이 뒤늦게 걸렸다. 실패 로그를 비우고 실행 시각을 비운 뒤에 그 값으로 집계한 것이다. 그 0건은 문제가 없다는 뜻이 아니라 아무것도 측정하지 못했다는 뜻이었다. 여기서도 원인은 순서였고 집계는 되돌림 이전에 했어야 했다.

되읽기의 함정

파일을 만들고 나서 만들어졌는지 확인할 때도 같은 문제가 있다. 만든 명령의 종료 코드가 0이면 성공으로 보게 되는데 종료 코드는 명령이 실행됐다는 뜻이지 의도한 상태가 됐다는 뜻이 아니다.

링크를 만드는 명령은 대상이 없어도 링크를 만든다. 개수를 세면 몇 개를 만들었다고 나오지만 그중 몇 개가 실제로 이어졌는지는 다른 문제다. 그래서 되읽기는 지정한 방식과 다른 방식으로 한다. 링크는 만든 개수가 아니라 해소되는지로 보고, 전송은 명령의 성공이 아니라 양쪽 해시로 보고, 생성은 반환값이 아니라 다시 조회한 개수와 이름으로 본다.

0건의 두 가지 뜻

빈 출력이나 0건이 나오면 두 가지 가능성이 있다. 정말 없는 것과 아무것도 측정하지 못한 것이다. 옵션 하나가 빠져 목록을 안 내거나 링크를 안 따라가거나 조건이 어긋나 대상이 안 잡히는 경우가 전부 0건으로 보인다.

가르는 방법은 대조군을 만드는 것이다. 통과가 나오면 실패해야 하는 입력으로 한 번 더 돌리고 실패가 나오면 성공해야 하는 입력으로 돌려 본다. 대조군이 같은 출력을 내면 그 검사는 아무것도 가르지 못한 것이다.

순서를 짜는 규칙

확인과 변경을 다른 호출로 나눈다. 한 블록 안에 넣으면 확인이 아니며 확인 결과를 눈으로 본 다음에 변경을 결정하는 구조여야 한다.

근거를 없애는 작업 전에 근거를 뽑는다. 초기화와 삭제와 리셋은 그 뒤에 할 조회를 무력화한다. 되읽기는 만든 명령이 알려 주는 값이 아니라 밖에서 다시 조회한 값으로 하고, 0건이 나오면 없는 것인지 못 잰 것인지 대조군으로 가른 뒤에 이유를 붙인다.

복구된 것과 안 된 것

덮어쓴 문서는 되살렸다. 다른 세션이 스크래치 영역에 원본을 복사해 둔 것이 남아 있었고 되돌린 뒤 차이를 대조해 원본에서 사라진 줄이 없는 것을 확인했다.

지운 파일 두 개는 어느 경로로도 되살리지 못했다. 판정 근거와 동의하지 않으면 그 사실을 남겨 달라는 요청을 관련 문서 양쪽에 적는 것으로 마무리했다. 되돌릴 수 없는 것은 되돌리는 대신 무엇을 근거로 그렇게 판단했는지를 남긴다.

정리


Share this post on:

Previous Post
BigQuery Legacy SQL 종료 — Standard SQL 전환 가이드
Next Post
AI가 화이트칼라를 대체할 때 — Citrini Research 분석 리뷰