pgrep -f와 pkill -f를 SSH로 사용했을 때, 대기 루프가 자기 자신을 35시간 동안 기다렸습니다

운영

10월 31일, SSH로 작은 루프를 시작했습니다. 다른 머신에서 번역 작업이 끝날 때까지 기다렸다가 후속 작업을 실행하는 루프였습니다. 번역 작업은 그날 밤에 끝났습니다. 이틀 후 다시 확인했을 때, 루프는 35시간 동안 대기 중이었고 후속 작업은 한 번도 실행되지 않았습니다.

루프의 정체

ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'

pgrep -f는 모든 프로세스의 전체 명령줄에서 패턴을 검색합니다. SSH는 따옴표로 묶은 명령을 bash -c 'while pgrep -f "i18n_job.py example.com" …' 형태로 실행하는데, 이 명령줄에 패턴이 포함되어 있습니다. pgrep는 자신의 프로세스는 결과에서 제외하지만, 이를 실행한 셸은 제외하지 않습니다. 따라서 루프가 살아 있는 한, 자기 자신과 일치하는 결과를 찾습니다.

형제 문제: pkill -f가 실행 중인 셸을 종료시킴

pkill -f에서도 같은 일이 발생하며, 결과는 더 심각합니다:

ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'

셸의 명령줄에 패턴이 포함되어 있으므로 pkill이 셸을 종료시킵니다. 워커는 중지되고 다시 시작되지 않으며, SSH는 오류 메시지 없이 종료 코드 255로 종료됩니다. 마치 따옴표 처리 문제처럼 보이며, 처음에는 그렇게 판단했습니다.

9월부터 10월 말까지 둘 중 하나에 최소 열두 번 이상 빠졌습니다. 실행되지 않은 재시작, 3시간 30분 동안 검사를 붙잡아 둔 루프, 50분 동안 번역 큐를 붙잡아 둔 다른 루프, 그리고 이 사례가 있었습니다.

현재의 해결책

Factory Floor, 저희 기계를 구동하는 키트는 systemd 유닛을 통해 작동합니다: 명령줄로 프로세스를 찾지 않습니다. 저희를 괴롭혔던 루프들은 직접 입력했던 루프들이었습니다.

업데이트됨: