💡 한 줄 요약
- 이 글은 리눅스 GUI 환경에서 당연하게 쓰지만 정확히는 모르고 지나가기 쉬운
Display,Screen,$DISPLAY환경변수,/tmp/.X11-unix소켓의 관계를, X 클라이언트-서버 통신 원리를 통해 정리한다. (Wayland/XWayland는 2부, 3부에서 다룬다)
🚨 1. 이 글을 쓰는 이유 및 대상 독자 {#1}
- 동기:
echo $DISPLAY를 치면:0같은 값이 나오는데, 이게 정확히 뭘 가리키는지, 왜:0이고:1은 뭔지, 소켓 파일과는 무슨 관계인지 설명 없이 그냥 "외워서" 쓰는 경우가 많다. - 대상 독자: 리눅스 GUI 환경(특히 임베디드 보드나 원격 SSH 환경)에서
$DISPLAY, X 서버 관련 에러를 마주쳐본 사람, 또는 X11의 내부 동작 원리가 궁금한 사람.
⚠️ 공통적인 Pain Point
SSH로 서버에 접속해서 GUI 앱을 띄우려다 cannot connect to X server 에러를 본 적이 있다면, 이 글이 그 원인을 이해하는 데 도움이 된다.
🛠️ 2. 사전 지식 & 개발 환경 {#2}
2.1 사전 지식
- 유닉스 도메인 소켓(Unix domain socket)의 기본 개념
- 클라이언트-서버 아키텍처에 대한 일반적인 이해
2.2 개발 환경
| 분류 | 기술 스택 / 도구 | 버전 | 비고 |
| OS | Ubuntu | 22.04 / 24.04 | 대부분의 배포판에서 동일 |
| 디스플레이 서버 | X.Org Server | 21.x | Xorg 기준 |
| 확인 도구 | xdpyinfo, xrandr, netstat |
- | 실습에 사용 |
🔍 3. 핵심 개념: Display와 Screen {#3}
X11 용어에서 서버(Server)와 클라이언트(Client)는 흔히 쓰는 웹 서버/클라이언트 감각과 반대다.
- X 서버: 모니터, 키보드, 마우스 같은 실제 하드웨어를 직접 제어하는 쪽. 데스크톱 컴퓨터 자체가 X 서버다.
- X 클라이언트: 그 하드웨어에 "이런 창을 그려줘"라고 요청하는 앱(파이어폭스, 터미널 등).
이 구도 위에 두 가지 논리적 단위가 있다.
- Display: 키보드 + 마우스 + 모니터(들)로 구성된 하나의 입출력 세트. 하나의 X 서버 프로세스가 관리하는 단위다.
- Screen: 하나의 Display 안에 속한 개별 물리 화면. 모니터 2대를 별도 Screen으로 구성하면
:0.0,:0.1처럼 구분된다. (참고로 요즘은 멀티모니터를 별도 Screen이 아니라 하나의 Screen 안에서 Xinerama/RandR로 확장하는 방식이 일반적이라, 실제로.1이상의 Screen 번호를 볼 일은 많지 않다)
$DISPLAY 환경변수는 이 둘을 다음 문법으로 표현한다.
[hostname]:displaynum[.screennum]
| 예시 | 의미 |
|---|---|
:0 |
로컬 머신의 0번 Display, Screen 생략(기본 0번) |
:0.1 |
로컬 머신의 0번 Display, 1번 Screen |
localhost:10.0 |
로컬호스트의 10번 Display (SSH 포워딩 시 흔히 보이는 번호대) |
🧪 4. 실습으로 확인하기 {#4}
# 현재 세션의 $DISPLAY 값 확인
echo $DISPLAY
# :0
# 해당 디스플레이에 대응하는 유닉스 소켓 확인
ls -la /tmp/.X11-unix/
# srwxrwxrwx 1 root root 0 ... X0
# 디스플레이 정보 상세 조회 (Screen 개수, 해상도 등)
xdpyinfo | head -20
:0이라는 값과 /tmp/.X11-unix/X0라는 파일명이 정확히 대응하는 것을 볼 수 있다. 이는 우연이 아니라 X11의 고정된 규칙이다.
🔬 5. 원인 분석: 클라이언트가 서버를 찾아가는 과정 {#5}
X 클라이언트(예: xterm)가 실행되면 내부적으로 다음 순서를 거친다.

핵심은 X 서버가 시작될 때 displaynum에 해당하는 유닉스 소켓 파일을 /tmp/.X11-unix/X<N> 경로에 미리 만들어 놓고 그 위에서 listen()하고 있다는 점이다. 클라이언트는 $DISPLAY에서 숫자만 뽑아내 이 소켓 경로를 그대로 조립해서 접속을 시도한다. 즉 :0이라는 짧은 문자열은 실제로는 "/tmp/.X11-unix/X0 소켓에 연결하라"는 지시나 다름없다.
원격 접속(hostname:10.0처럼 호스트명이 붙은 경우)은 경로가 다르다. 이때는 유닉스 소켓 대신 TCP 6000+N번 포트(예: 10번 디스플레이면 6010번)로 접속하며, SSH X11 포워딩(ssh -X)은 이 TCP 연결을 SSH 터널 안으로 감싸서 전달하는 방식이다. 로컬 소켓과 원격 TCP, 두 경로 모두 최종적으로는 같은 X11 프로토콜 메시지를 주고받는다는 점은 동일하다.
💡 6. 흔한 오해 {#6}
- ❌ "
$DISPLAY가 없으면 X 서버가 없다" →$DISPLAY는 어디에 접속할지를 알려주는 주소일 뿐, X 서버 존재 여부와는 별개다. 환경변수만 안 잡혀 있을 수도 있다. - ❌ "Display 번호는 모니터 개수와 같다" → Display 번호는 세션(로그인 인스턴스) 단위다. 모니터 여러 대는 보통 하나의 Display, 하나의 Screen 안에서 RandR로 확장된다.
- ❌ "소켓 파일이 있으면 X 서버가 살아있다" → 비정상 종료 시 소켓 파일이 남아있는데 서버 프로세스는 죽어있는 경우도 있다(stale socket).
xdpyinfo처럼 실제로 프로토콜 통신을 해보는 것이 확실하다.
🏁 7. 마무리 {#7}
7.1 결론
$DISPLAY는 단순한 환경변수가 아니라, X 클라이언트가 X 서버의 유닉스 소켓(또는 TCP 포트) 주소를 조립하기 위한 규격화된 문자열이다. Display는 입출력 세트 단위, Screen은 그 안의 물리 화면 단위이며, /tmp/.X11-unix/X<N> 소켓이 이 모든 것을 실제 통신 채널로 연결한다.
7.2 참고 자료
- X.Org Foundation - X Window System Protocol
man X(Xorg 매뉴얼 페이지)
7.3 다음 단계
- 2부: Wayland와 컴포지터 — X11의 3자 구도(클라이언트-서버-WM)가 Wayland에서 어떻게 클라이언트-컴포지터 2자 구도로 재편되는지
- 3부: XWayland — Wayland 세션에서 X11 앱이 어떻게
$DISPLAY와 소켓을 다시 만들어내며 동작하는지
'잡(job)기술' 카테고리의 다른 글
| XWayland: 두 세계를 잇는 다리, 그리고 종합 정리 (0) | 2026.09.21 |
|---|---|
| Wayland와 컴포지터: X11과는 다른 설계 (0) | 2026.09.21 |
| [Troubleshooting] 우분투 원격 데스크톱(RDP) 활성화 및 인증 오류(0x0) 해결 가이드 (0) | 2026.07.02 |
| [Jetson Orin NX] Ubuntu 24.04 GDM3 설정을 통해 Wayland 세션 활성화하기 (0) | 2026.07.02 |
| C++ 프로젝트가 나뉘어 있다면, CMake로 한 번에 묶어 빌드하자 - 그리고 Sanitizer는 꼭 붙이자 (1) | 2026.02.26 |