PowerShell 프로세스 PID 종료, AI 에이전트가 옆 프로젝트 서버를 세 번 끈 뒤 정한 규칙
한 PC 에서 웹게임 세 개를 같이 만들고 있다. TEXT WAR 는 8800, 탑 게임은 8810번대, 좀비 게임은 8820 포트에 개발 서버를 띄운다. 셋 다 Python 이라 작업 관리자를 열면 python.exe 가 줄줄이 보인다. 그날 좀비 게임 개발 서버가 자꾸 죽었다. 기록에는 세 번 꺼졌다고 남아 있다.
원인은 옆 프로젝트였다. 탑 게임 쪽에서 AI 에이전트로 개발 작업을 돌리고 있었는데, 그 에이전트가 python 프로세스 중 명령줄에 devserver.py 나 pytest 가 들어간 걸 경로 구분 없이 꺼 버렸다. 좀비 게임 서버 스크립트 이름도 devserver.py 였다. 그래서 그 뒤로는 PowerShell 프로세스 PID 종료만 쓴다. 내가 띄운 프로세스의 PID 를 받아 두고 그 번호로만 끈다. 번호를 놓쳤으면 내 포트를 잡고 있는 프로세스를 찾아서 그 PID 로 끈다.

옆 프로젝트 프로세스가 세 번 꺼진 날
9월 30일 일이다. 탑 게임은 개발 작업을 여러 갈래로 나눠 AI 에이전트들한테 맡기는 흐름으로 돌리고 있었다. 기능 하나 만들고, 검토하고, 고치고, 전체 시험 돌리고. 그 흐름 어딘가에서 에이전트가 프로세스를 정리하다 사고가 났다.
에이전트가 쓴 명령은 대충 이런 식이었다. python 프로세스를 다 훑어서 명령줄에 devserver.py 나 pytest 가 들어 있으면 끈다. 어느 폴더에서 뜬 건지는 안 봤다. 내가 다시 본 작업 기록에는 명령 원문 없이 이 설명만 남아 있다.
알아챈 건 좀비 게임 쪽이었다. 그쪽 세션에서 개발 서버 8820 이 세 번 꺼졌다고 알려 왔다. 세 프로젝트 서버 스크립트가 전부 scripts 폴더의 devserver.py 라서, 글자만 보고 고르면 셋이 구별이 안 된다. 같은 PC 에서 돌던 다른 프로젝트 서버까지 끌 대상에 들어간 거다.
PID 로 끄는 규칙을 정하기까지
사고 뒤에는 탑 게임 쪽 작업 흐름을 멈추고, 남은 탑 게임 프로세스 2개를 PID 로 껐다. 탑 게임 공통 규칙에는 프로세스 끄기 절을 새로 넣었다. 좀비 게임 쪽 기록에도 같은 금지 규칙을 넣고 개발 서버 8820 을 다시 띄웠다고 남아 있다.
규칙은 이렇다. 끄는 건 내가 띄운 것만. 방법은 둘 중 하나다. 띄울 때 받은 PID 로 끄거나, 내 포트를 잡고 있는 프로세스의 PID 로 끈다. 명령줄 글자로 고를 수밖에 없으면 경로랑 포트를 둘 다 조건에 넣는다.
반대로 이름만 보고 여러 개를 한꺼번에 끄는 건 금지했다.
# 금지: 이름만으로 한꺼번에 끄기
Get-Process python | Stop-Process
taskkill /IM python.exe /F
아래 줄은 조회만 한다. 다만 이렇게 devserver.py 라는 글자만으로 고른 결과를 그대로 끌 대상으로 쓰는 것도 금지했다. 세 프로젝트가 다 걸리니까. 사고 기록에 남은 게 바로 이런 조건으로 고른 프로세스를 경로 구분 없이 끈 거다.
Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like '*devserver.py*' }
이 규칙은 나중에 모든 프로젝트 공통 지침에도 들어갔다.
PowerShell 프로세스 PID 종료, 직접 돌려 봤다
오늘 이 PC 에서 PID 로 끌 대상을 골라내는 과정을 다시 해 봤다. 다른 프로젝트 포트를 피해서 8095, 8096 에 node 로 아주 작은 웹 서버를 두 개 띄웠다.
$a = Start-Process node -ArgumentList '-e',"<서버 코드>",'8095' -PassThru
$b = Start-Process node -ArgumentList '-e',"<서버 코드>",'8096' -PassThru
$a.Id; $b.Id
여기서 챙길 건 -PassThru 하나다. Start-Process 문서를 보면 기본으로는 아무것도 안 돌려주고, 이걸 붙여야 방금 띄운 프로세스 객체를 돌려준다. 그 객체의 .Id 가 PID 다. 이번엔 8524 랑 1720 이 나왔다. 이 번호를 적어 두면 나중에 끌 때 고민할 게 없다.
그 순간 (Get-Process node).Count 를 찍어 보니 3 이었다. 이번에 띄운 건 2개인데 node 가 하나 더 있었다. 그 하나가 어느 작업에서 뜬 건지는 이 출력만으론 모른다. 여기서 이름으로 끌 대상을 골랐으면 그것까지 들어갔을 거다. 9월 30일이랑 똑같은 모양이다.
포트로 프로세스 주인 찾기
PID 를 안 적어 뒀으면? 서버라면 포트로 찾으면 된다.
Get-NetTCPConnection -LocalPort 8095 -State Listen | Select OwningProcess
OwningProcess 가 8524 로 나왔다. 아까 받은 PID 랑 같다. 다만 포트 번호만 믿으면 안 되는 경우가 있다. 그 포트를 내가 아니라 다른 프로그램이 잡고 있을 수도 있으니까. 그럴 땐 그 PID 의 명령줄을 한 번 열어 보고 내 경로가 맞는지 보고 끈다.
taskkill 로 PID 하나만 끄기
taskkill /T /F /PID $a.Id
taskkill 문서에 따르면 /F 는 강제로 끄고, /T 는 그 프로세스가 띄운 자식 프로세스까지 같이 끈다. 출력에 두 줄이 나왔다. 자식 프로세스 하나가 먼저 꺼지고 8524 가 꺼졌다. 서버가 자식을 따로 띄우는 경우가 있으니까 /T 를 붙여 두는 게 편하다. 같은 문서에 /IM 으로 이미지 이름을 줘서 끄는 방법도 있는데, 앞에서 금지한 게 바로 그쪽이다.
그다음 8096 에 요청을 보내 봤다. 200. 옆 서버는 멀쩡히 살아 있었다. 마지막으로 $b.Id 도 같은 식으로 끄고, 두 PID 를 다시 조회해서 아무것도 안 남은 걸 봤다.
이름으로 끄면 안 되는 이유, 내 경우
결국 한 PC 에 비슷한 프로젝트를 여러 개 띄우면 프로세스 이름은 거의 다 같다. python.exe, node.exe 같은 것. 이름이나 흔한 파일 이름으로 고르면 내 것만 골라낼 방법이 없다. 그래서 AI 에이전트한테 일을 맡길 때도 서버나 시험을 띄우면 PID 를 적어 두고, 끝나면 그 PID 로 끄라고 지침에 박아 뒀다. 끌 게 애매하면 끄지 말고 알려 달라고도.
윈도우에서 AI 코딩 도구를 쓰다 막힌 다른 얘기는 Codex 샌드박스 오류 글이랑 처음 깔 때 점검표에 적어 뒀다.
다음엔 워드프레스 대신 Node 로 정적 블로그를 만든 구조를 한 번에 볼 수 있게 적으려고 한다.