트러블슈팅 3. plink 로 "sudo bash -s" < 스크립트를 넘겼더니 docker compose exec 뒤가 실행되지 않음 - PCMEISTER 기술 노트
본문 글자 크기

트러블슈팅 3. plink 로 "sudo bash -s" < 스크립트를 넘겼더니 docker compose exec 뒤가 실행되지 않음

집 PC 가 Windows 라 리눅스 서버 작업은 PuTTY 의 plink 로 합니다. 짧은 명령은 따옴표 안에 넣으면 되지만 길어지면 스크립트 파일을 만들어서 표준입력으로 넘기는 게 편하더군요.

plink -batch -i key.ppk opc@서버 "sudo bash -s" < restore.sh

사내 채팅(Zulip)을 새 노드로 옮기는 리허설에서 복원 스크립트를 이렇게 돌렸습니다. 데이터베이스 컨테이너를 먼저 띄우고, docker compose exec 로 그 안에서 복원 명령을 돌린 다음, 나머지 서비스를 올리는 스크립트였습니다.

끝나고 확인해 보니 데이터베이스만 떠 있었습니다. 복원도, 그 뒤의 서비스 기동도 안 된 상태였고요.


bash -s 는 실행할 스크립트를 표준입력에서 조금씩 읽어 가며 실행합니다. 그런데 docker compose exec 는 기본으로 표준입력을 컨테이너 안 프로세스에 연결합니다. 그러니 첫 번째 docker compose exec 가 실행되는 순간, bash 가 아직 읽지 않은 스크립트의 나머지를 컨테이너 안의 명령이 받아 가 버립니다. 그 명령이 끝나면 bash 는 더 읽을 게 없으니 거기서 끝납니다.

docker exec 는 -i 를 줘야 표준입력을 넘기니 이런 일이 없는데, docker compose exec 는 반대로 기본이 켜져 있어서 헷갈리기 쉽습니다. -T 는 TTY 만 끄는 옵션이라 이걸로는 안 막힙니다.

고치는 방법은 둘입니다. 스크립트 안의 docker compose exec 마다 표준입력을 막거나,

docker compose exec database psql -U zulip -c 'select 1' < /dev/null

스크립트를 표준입력으로 넘기지 말고 파일로 올려서 실행하는 겁니다.

pscp -batch -i key.ppk restore.sh opc@서버:/tmp/restore.sh
plink -batch -i key.ppk opc@서버 "sudo bash /tmp/restore.sh"

저는 둘 다 합니다. 스크립트는 파일로 올리고, 그 안의 exec 에도 < /dev/null 을 붙여 둡니다. 이 일 뒤로 원격에서 돌리는 스크립트에 docker compose exec 가 보이면 습관처럼 끝을 확인하게 됐습니다.

트러블슈팅 시리즈의 글

완료 글 30개 인터넷