리눅스 screen 명령어 사용법 - 세션을 서버에 남기고 다시 붙기
이 명령어를 언제 쓰는가
세 시간짜리 마이그레이션을 돌리는 중에 VPN이 끊겼다. nohup으로 띄웠다면 프로세스는 살아 있겠지만 화면은 사라진다. 진행 상황을 보려면 로그를 뒤져야 하고, 중간에 대화형 입력을 요구하는 도구였다면 그대로 멈춰 있다.
screen은 접근이 다르다. 명령이 아니라 터미널 세션 자체를 서버에 남긴다. 접속이 끊겨도 세션은 서버에서 계속 돌고, 다시 접속해 screen -r 한 줄이면 화면이 끊겼던 그 상태 그대로 돌아온다. 스크롤백도 살아 있고 입력도 그대로 이어서 할 수 있다.
선택 기준은 명확하다. 결과만 로그로 확인하면 되는 일방향 작업은 nohup, 보면서 판단하고 개입해야 하는 작업은 screen이나 tmux다. DB 마이그레이션, 대화형 설치 스크립트, 장애 대응 중 여러 명령을 오가는 상황이 후자에 해당한다.
기본 형식
screen -S 세션이름 # 새 세션 만들고 들어가기
Ctrl+a 다음에 d # 세션에서 빠져나오기(분리)
screen -ls # 세션 목록 확인
screen -r 세션이름 # 다시 붙기
핵심은 Ctrl+a다. screen에서는 이 조합이 프리픽스 키다. Ctrl+a를 누르고 손을 뗀 뒤, 이어서 명령 키를 누른다. Ctrl+a와 d를 동시에 누르는 것이 아니다.
자주 쓰는 옵션과 키
| 명령·키 | 의미 | 비고 |
|---|---|---|
screen -S 이름 | 이름을 붙여 새 세션 시작 | 이름을 안 주면 PID만 남아 나중에 알아보기 어렵다 |
screen -ls | 세션 목록 | Attached / Detached 상태가 보인다 |
screen -r 이름 | 분리된 세션에 다시 붙기 | 세션이 하나뿐이면 이름 생략 가능 |
screen -d -r 이름 | 다른 곳에 붙어 있는 세션을 강제로 떼고 붙기 | 가장 자주 쓰게 되는 형태 |
screen -x 이름 | 같은 세션에 동시에 붙기 | 둘이 같은 화면을 본다. 원격 페어 작업용 |
screen -dmS 이름 명령 | 분리 상태로 바로 시작 | 스크립트·크론에서 쓴다 |
screen -S 이름 -X quit | 세션 종료 | 붙지 않고 밖에서 끝낸다 |
Ctrl+a → d | 분리(detach) | 가장 중요한 키 |
Ctrl+a → c | 새 창 만들기 | 한 세션 안에 여러 창 |
Ctrl+a → n / p | 다음 창 / 이전 창 | |
Ctrl+a → " | 창 목록에서 골라 이동 | 창이 많아지면 필수 |
Ctrl+a → Esc | 복사·스크롤 모드 | 방향키로 스크롤, q로 나온다 |
Ctrl+a → ? | 키 바인딩 도움말 | 기억이 안 날 때 |
실전 예제
1) 장시간 마이그레이션을 세션에 담아 돌린다. 가장 기본적인 흐름이다.
screen -S migrate
# 세션 안에서
./migrate_users.sh
# 진행 상황을 보다가 자리를 뜨려면 Ctrl+a 다음 d
[detached from 42669.migrate]
나중에 다시 접속해서 붙는다.
screen -ls
There is a screen on:
42669.migrate (Detached)
1 Socket in /run/screen/S-hscho.
screen -r migrate
2) 스크립트나 크론에서 세션을 미리 띄운다. 붙지 않은 채로 시작해 두고, 필요할 때만 들어가 확인하는 방식이다.
screen -dmS batch bash -c '/opt/jobs/nightly.sh; exec bash'
끝에 exec bash를 붙인 이유가 있다. 이게 없으면 스크립트가 끝나는 순간 세션도 함께 사라져서 결과 화면을 볼 기회가 없다. 셸을 하나 남겨 두면 종료 후에도 화면이 유지된다.
3) 세션 출력을 파일로도 남긴다. 나중에 이력을 제출해야 하는 작업이라면 로깅을 켠다.
screen -L -Logfile /var/log/migrate_session.log -S migrate
세션 안에서 Ctrl+a → H로 로깅을 켜고 끌 수도 있다. 오래된 screen(4.05 이전)에는 -Logfile 옵션이 없어 현재 디렉터리에 screenlog.0이 만들어진다.
4) 동료와 같은 화면을 보며 장애를 잡는다. -r은 한 명만 붙지만 -x는 여러 명이 동시에 붙는다. 같은 계정으로 접속해 있어야 한다.
screen -x incident
5) 붙지 않고 밖에서 세션을 정리한다. 남아 있는 세션이 자원을 잡고 있을 때 쓴다.
screen -ls
screen -S batch -X quit
screen -wipe # 죽었는데 목록에 남은 항목 정리
6) 스크롤백을 늘려 둔다. 기본 100줄은 실무에서 턱없이 부족하다. ~/.screenrc에 넣는다.
defscrollback 20000
startup_message off
escape ^Bb
hardstatus alwayslastline '%{= kG}[%H] %{= kw}%-Lw%{= kG}%50>%n%f* %t%{= kw}%+Lw%<'
escape ^Bb는 프리픽스를 Ctrl+a에서 Ctrl+b로 바꾼다는 뜻이다. 이유는 아래에서 설명한다.
함정과 주의점
Ctrl+a가 셸의 줄 맨 앞으로 이동 키와 충돌한다. bash와 zsh의 emacs 키 바인딩에서 Ctrl+a는 커서를 줄 처음으로 보내는 키다. screen 안에서는 이 키를 screen이 먼저 가로챈다. 긴 명령을 고치려고 Ctrl+a를 눌렀다가 화면이 이상해지는 일이 매일 벌어진다. 두 가지 해법이 있다. 하나는 Ctrl+a → a를 눌러 진짜 Ctrl+a를 셸에 전달하는 것이고, 다른 하나는 .screenrc에서 프리픽스를 Ctrl+b 등으로 바꾸는 것이다. 후자를 권한다.
screen -r이 안 붙는다. 네트워크가 끊겨도 서버 쪽 screen은 자기가 아직 붙어 있다고 생각한다. 그래서 다시 접속해 screen -r을 치면 이런 메시지가 나온다.
There is a screen on:
42669.migrate (Attached)
There is no screen to be resumed matching migrate.
screen -d -r migrate를 쓴다. 기존 연결을 강제로 떼어내고(-d) 붙는다(-r). 이 조합을 아예 기본으로 쓰는 편이 편하다.
screen 세션은 재부팅을 넘기지 못한다. 당연하지만 사고가 난 뒤에야 떠올리는 사실이다. 서버가 재부팅되면 세션도 그 안의 프로세스도 전부 사라진다. 계속 떠 있어야 하는 것은 반드시 systemd 유닛으로 등록한다. screen은 사람이 붙었다 떼었다 하는 일회성 작업을 위한 도구다.
RHEL 계열에서는 screen이 기본 저장소에 없다. Red Hat은 RHEL 8부터 screen을 deprecated로 표시하고 tmux를 표준으로 삼았다. RHEL·Rocky·AlmaLinux 8 이상에서 screen을 쓰려면 EPEL 저장소를 붙여야 한다. Ubuntu·Debian에는 여전히 screen 패키지가 정상 제공된다. 새로 배우는 입장이라면 tmux 쪽에 시간을 쓰는 것이 낫다. screen을 알아 둘 가치는 여전히 있는데, 오래된 서버나 손댈 수 없는 어플라이언스에는 screen만 있는 경우가 많기 때문이다.
macOS에 딸려 오는 screen은 매우 낡았다. screen --version을 찍어 보면 4.00.03(2006년)이 나온다. -Logfile 같은 옵션이 없고 동작도 조금씩 다르다. 맥에서 실제로 쓸 일이 있다면 brew install screen으로 최신 버전을 넣거나 tmux를 쓴다.
세션 안의 환경변수는 붙은 시점에 고정된다. 오래된 세션에 다시 붙으면 SSH_AUTH_SOCK이 이미 사라진 옛 소켓을 가리켜서 에이전트 포워딩이 동작하지 않는다. ssh-add -l이 Could not open a connection to your authentication agent를 뱉으면 이 경우다. 세션 안에서 환경변수를 새로 넣어 주면 된다.
export SSH_AUTH_SOCK=$(ls -t /tmp/ssh-*/agent.* 2>/dev/null | head -1)
세션이 방치되어 쌓인다. screen -ls가 열 개 넘게 나오는 서버를 흔히 본다. 각 세션이 셸과 그 자식 프로세스를 붙들고 있어 메모리를 먹고, 무엇보다 어느 세션이 진짜 돌고 있는 작업인지 알 수 없어진다. 세션 이름을 작업 기준으로 짓고(migrate-20260825), 끝난 세션은 그 자리에서 exit로 닫는다.
함께 보면 좋은 명령어
- tmux — 같은 일을 하는 요즘 표준. 창 분할, 스크립트 제어, 설정 문법이 모두 낫다. 새로 시작한다면 이쪽이다.
- nohup — 화면을 볼 필요가 없는 단방향 배치라면 세션을 띄울 것 없이 nohup이 더 가볍다.
- systemctl — 계속 살아 있어야 하는 서비스는 screen이 아니라 systemd 유닛으로 등록한다.