Skip to content

Commit f6938f4

Browse files
committed
post
1 parent 2d95a91 commit f6938f4

File tree

4 files changed

+328
-0
lines changed

4 files changed

+328
-0
lines changed

posts/etc/layer-keymapping.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
키가 부족해서 오른쪽 option, shift를 레이어 키로 쓰기로 함. via는 안쓰고 맥북에서도 동일한 레이아웃을 원하기 때문에 karabiner로 탭 기능 구현.
2+
3+
맥북 쓸 때는 f19, f20을 썼는데, f키는 모디파이어가 아니라서 홀드해도 홀드 상태로 인식되지 않고, 반복 입력이 발생함.
4+
그래서 조합을 할 수 없었음.
5+
6+
그런데! 오늘 karabiner-eventviewer로 다시 해보니 f20-f24는 반복 입력이 없었음. 바로 시도 ㄱㄱ

posts/etc/macos-korean-nfd.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
title: "macOS에서 한글 파일명이 깨지는 이유(NFD)"
3+
slug: macos-korean-nfd
4+
created: 2026-02-07
5+
category: etc
6+
type: [til]
7+
tags: []
8+
---
9+
10+
## 증상
11+
12+
macOS에서 만든 한글 파일명이 Windows나 Linux, 또는 일부 프로그램에서 자모가 분리되어 보이는 현상이 있다.
13+
예를 들어 `김범수 - 지나간다.opus``ㄱㅣㅁㅂㅓㅁㅅㅜ - ㅈㅣㄴㅏㄱㅏㄴㄷㅏ.opus`처럼 풀어져서 표시된다.
14+
15+
맥의 Finder에서 파일명을 한글로 변경했을 때 이런 현상이 발생하고, 터미널에서 `ls`로 출력해보면 글자가 깨져서 나온다.
16+
터미널에서 `mv`로 변경했을 때는 발생하지 않았다.
17+
18+
## 원인: 유니코드 정규화 (NFC vs NFD)
19+
20+
유니코드는 같은 글자를 표현하는 두 가지 방식을 정의하고 있다.
21+
22+
### NFC (Normalization Form Composed) — 완성형
23+
24+
한글을 **완성된 한 글자**로 저장하는 방식이다.
25+
26+
```
27+
"한" = U+D55C (1개의 코드 포인트)
28+
```
29+
30+
Windows, Linux 등 대부분의 시스템이 이 방식을 사용한다.
31+
32+
### NFD (Normalization Form Decomposed) — 분해형
33+
34+
한글을 **초성 + 중성 + 종성**으로 분해하여 저장하는 방식이다.
35+
36+
```
37+
"한" = ㅎ(U+1112) + ㅏ(U+1161) + ㄴ(U+11AB) (3개의 코드 포인트)
38+
```
39+
40+
macOS의 파일시스템(APFS, HFS+)이 이 방식을 사용한다.
41+
42+
### 비교
43+
44+
| | NFC (완성형) | NFD (분해형) |
45+
|---|---|---|
46+
| `` 저장 방식 | `U+D55C` (1개) | `U+1112 U+1161 U+11AB` (3개) |
47+
| 사용 환경 | Windows, Linux | macOS |
48+
| 눈에 보이는 차이 | 없음 (같은 글자로 렌더링) | 없음 (같은 글자로 렌더링) |
49+
| 바이트 수 | 적다 | 많다 |
50+
51+
눈으로 보기에 같은 글자이지만 내부적으로 다른 바이트 시퀀스이기 때문에, NFD를 지원하지 않는 환경에서는 자모가 풀어져서 보이게 된다.
52+
53+
## 확인 방법
54+
55+
Python으로 파일명의 정규화 형태를 확인할 수 있다.
56+
57+
```python
58+
import os, unicodedata
59+
60+
for f in os.listdir('/path/to/dir'):
61+
is_nfc = unicodedata.is_normalized('NFC', f)
62+
print(f'NFC={is_nfc} {f}')
63+
```
64+
65+
macOS에서 생성한 한글 파일명은 대부분 `NFC=False`로 표시된다.
66+
67+
## 해결 방법
68+
69+
NFD로 저장된 파일명을 NFC로 변환하면 된다.
70+
71+
### Python (macOS 기본 설치)
72+
73+
```bash
74+
python3 -c "
75+
import os, unicodedata
76+
path = '/path/to/dir'
77+
for f in os.listdir(path):
78+
nfc = unicodedata.normalize('NFC', f)
79+
if f != nfc:
80+
os.rename(os.path.join(path, f), os.path.join(path, nfc))
81+
print('변환:', nfc)
82+
"
83+
```
84+
85+
### convmv (전용 도구)
86+
87+
```bash
88+
# 설치
89+
brew install convmv
90+
91+
# 미리보기 (실제 변환하지 않음)
92+
convmv -f utf8 -t utf8 --nfc /path/to/dir/*
93+
94+
# 실제 변환
95+
convmv -f utf8 -t utf8 --nfc --notest /path/to/dir/*
96+
```
97+
98+
Python은 macOS에 기본 포함되어 있어서 별도 설치 없이 바로 사용할 수 있다.
99+
convmv는 Homebrew 설치가 필요하지만 명령어가 더 간결하다.

posts/etc/tmux-musikcube-popup.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: "tmux에서 플로팅 팝업으로 별도 세션 사용하기"
3+
slug: tmux-musikcube-popup
4+
created: 2026-02-07
5+
category: etc
6+
type: [til]
7+
tags: []
8+
---
9+
10+
## 목표
11+
12+
tmux 작업 중 어디서든 단축키 하나로 musikcube를 플로팅 팝업으로 열고, 음악을 재생한 상태로 팝업을 닫을 수 있도록 설정하는 것이다.
13+
14+
## display-popup
15+
16+
tmux 3.2부터 `display-popup` 명령이 추가되었다. 현재 창 위에 플로팅 윈도우를 띄우는 기능이다.
17+
18+
```bash
19+
# 기본 사용법
20+
tmux display-popup -w 80% -h 80% "명령어"
21+
```
22+
23+
주요 옵션은 다음과 같다.
24+
25+
| 옵션 | 설명 |
26+
|------|------|
27+
| `-w`, `-h` | 팝업 너비, 높이 (퍼센트 또는 절대값) |
28+
| `-E` | 명령이 종료되면 팝업도 닫힘 |
29+
| `-d` | 팝업의 작업 디렉토리 지정 |
30+
31+
## 단순한 방법 (문제 있음)
32+
33+
가장 직관적인 설정은 다음과 같다.
34+
35+
```bash
36+
# tmux.conf
37+
bind-key m display-popup -E -w 80% -h 80% "musikcube"
38+
```
39+
40+
이 방법은 팝업이 잘 열리지만, **팝업을 닫으면 musikcube 프로세스도 함께 종료**된다.
41+
`display-popup`은 내부에서 실행 중인 프로세스의 생명주기를 관리하기 때문에, 팝업을 닫는 순간 musikcube에 SIGHUP이 전달되어 종료되는 것이다.
42+
43+
음악을 재생한 상태로 팝업만 닫으려면 다른 접근이 필요하다.
44+
45+
## 해결: 별도 tmux 서버 사용
46+
47+
musikcube를 **별도의 tmux 서버**에서 실행하고, 팝업은 그 세션에 attach/detach만 하는 것이다.
48+
49+
```bash
50+
# tmux.conf
51+
bind-key m display-popup -E -w 80% -h 80% "tmux -L Music new-session -A -s Music 'musikcube'"
52+
```
53+
54+
### 동작 방식
55+
56+
1. `tmux -L Music``Music`이라는 이름의 **별도 소켓**으로 독립된 tmux 서버를 실행한다
57+
2. `new-session -A -s Music``Music` 세션이 있으면 attach, 없으면 새로 생성한다
58+
3. `'musikcube'` — 해당 세션에서 musikcube를 실행한다
59+
4. `-E` — 팝업 내 명령(attach)이 종료되면 팝업을 닫는다
60+
61+
### 사용법
62+
63+
| 동작 ||
64+
|------|-----|
65+
| 팝업 열기 | `prefix``m` |
66+
| 팝업 닫기 (음악 유지) | `prefix``d` |
67+
| 다시 열기 | `prefix``m` |
68+
69+
팝업 안에서 `prefix + d`를 누르면 별도 서버의 세션에서 detach되면서 팝업이 닫힌다.
70+
musikcube는 별도 서버에서 계속 실행 중이므로 음악이 끊기지 않는다.
71+
다시 `prefix + m`을 누르면 `-A` 플래그 덕분에 기존 세션에 재접속된다.

posts/etc/tmux-server-socket.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: "tmux 서버와 소켓 구조"
3+
slug: tmux-server-socket
4+
created: 2026-02-07
5+
category: etc
6+
type: [til]
7+
tags: []
8+
---
9+
10+
## tmux의 서버-클라이언트 구조
11+
12+
tmux는 단순한 터미널 멀티플렉서처럼 보이지만, 내부적으로는 **서버-클라이언트 구조**로 동작한다.
13+
14+
```
15+
터미널 (클라이언트) ──소켓──▶ tmux 서버 ─┬─ session A ─┬─ window 1 ─┬─ pane 1
16+
│ │ └─ pane 2
17+
│ └─ window 2 ─── pane 1
18+
└─ session B ─── window 1 ─── pane 1
19+
```
20+
21+
- **서버**: 모든 세션, 윈도우, 팬을 관리하는 백그라운드 프로세스이다. 세션 안에서 실행되는 모든 프로그램의 생명주기를 서버가 관리한다.
22+
- **클라이언트**: 터미널이 서버에 접속하여 화면을 렌더링하는 역할이다. `tmux attach`로 접속하고 `tmux detach`로 빠져나온다.
23+
24+
이 구조 덕분에 터미널을 닫아도(클라이언트 종료) 서버에서 실행 중인 프로세스는 계속 살아있는 것이다.
25+
SSH 세션이 끊어져도 작업이 유지되는 이유이기도 하다.
26+
27+
## 유닉스 소켓을 통한 통신
28+
29+
서버와 클라이언트는 **유닉스 도메인 소켓**(Unix Domain Socket)을 통해 통신한다.
30+
유닉스 소켓은 같은 시스템 내에서 프로세스 간 통신(IPC)을 하기 위한 메커니즘으로, 파일시스템에 소켓 파일 형태로 존재한다.
31+
32+
소켓 파일은 `/tmp/tmux-{UID}/` 디렉토리에 위치한다.
33+
34+
```bash
35+
$ ls -la /tmp/tmux-501/
36+
srwxrwx--- jay wheel 0 B default
37+
```
38+
39+
`s`로 시작하는 파일 타입이 소켓 파일이다.
40+
`tmux`를 처음 실행하면 `default`라는 이름의 소켓 파일이 생성되고, 이후 모든 `tmux` 명령은 이 소켓을 통해 서버와 통신한다.
41+
42+
```bash
43+
# 아래 두 명령은 동일하다
44+
tmux new-session -s work
45+
tmux -L default new-session -s work
46+
```
47+
48+
`-L` 옵션을 생략하면 자동으로 `default` 소켓을 사용하는 것이다.
49+
50+
## -L 옵션: 별도 서버 실행
51+
52+
`-L` 옵션은 소켓 이름을 지정한다. 소켓이 다르면 **완전히 독립된 별도 서버**가 실행된다.
53+
54+
```bash
55+
# 기본 서버 (소켓: default)
56+
tmux new-session -s work
57+
58+
# 별도 서버 (소켓: Music)
59+
tmux -L Music new-session -s Music
60+
```
61+
62+
이렇게 하면 소켓이 두 개가 된다.
63+
64+
```bash
65+
$ ls /tmp/tmux-501/
66+
default # 기본 서버
67+
Music # 별도 서버
68+
```
69+
70+
각 소켓은 독립된 서버 프로세스를 가지며, 서로 완전히 격리되어 있다.
71+
72+
### 독립되는 것들
73+
74+
**설정 독립**
75+
76+
각 서버는 자체 설정을 가진다.
77+
기본 서버에서 prefix를 `Ctrl+a`로 바꿨더라도, `-L Music`으로 띄운 서버는 기본값인 `Ctrl+b`를 사용한다.
78+
별도 서버에 다른 설정을 적용하고 싶다면 `-f` 옵션으로 설정 파일을 지정하면 된다.
79+
80+
```bash
81+
tmux -L Music -f ~/.config/tmux/music.conf new-session -s Music
82+
```
83+
84+
**세션 독립**
85+
86+
`tmux ls`는 기본 서버의 세션만 보여준다.
87+
별도 서버의 세션을 확인하려면 `-L` 옵션을 명시해야 한다.
88+
89+
```bash
90+
# 기본 서버 세션 목록
91+
tmux ls
92+
93+
# Music 서버 세션 목록
94+
tmux -L Music ls
95+
```
96+
97+
**프로세스 독립**
98+
99+
서버가 다르면 프로세스도 완전히 분리된다.
100+
기본 서버를 `tmux kill-server`로 종료해도 Music 서버는 영향받지 않는다.
101+
102+
```bash
103+
# 기본 서버만 종료 (Music 서버는 살아있음)
104+
tmux kill-server
105+
106+
# Music 서버 종료
107+
tmux -L Music kill-server
108+
```
109+
110+
## -S 옵션: 소켓 경로 직접 지정
111+
112+
`-L`은 소켓 **이름**을 지정하며 파일은 `/tmp/tmux-{UID}/` 아래에 생성된다.
113+
소켓 파일의 **전체 경로**를 직접 지정하고 싶다면 `-S` 옵션을 사용한다.
114+
115+
```bash
116+
tmux -S /var/run/tmux/my-server new-session
117+
```
118+
119+
`-L``-S`의 차이는 다음과 같다.
120+
121+
| 옵션 | 소켓 경로 | 예시 |
122+
|------|----------|------|
123+
| `-L Music` | `/tmp/tmux-{UID}/Music` | 이름만 지정 |
124+
| `-S /path/to/sock` | `/path/to/sock` | 전체 경로 지정 |
125+
126+
일반적인 용도에서는 `-L`만으로 충분하다.
127+
128+
## 활용 예시
129+
130+
별도 서버가 유용한 상황은 다음과 같다.
131+
132+
**설정 충돌 방지**
133+
134+
tmux 팝업(`display-popup`) 안에서 tmux 세션을 사용할 때, 별도 서버를 사용하면 prefix 키가 충돌하지 않는다.
135+
136+
```bash
137+
# tmux.conf (prefix: Ctrl+a)
138+
bind-key m display-popup -E -w 80% -h 80% "tmux -L Music new-session -A -s Music 'musikcube'"
139+
# 팝업 안의 Music 서버는 prefix가 Ctrl+b이므로 충돌 없음
140+
```
141+
142+
**격리된 환경 구성**
143+
144+
특정 프로젝트나 용도별로 서버를 완전히 분리할 수 있다.
145+
146+
```bash
147+
# 개발용 서버
148+
tmux -L dev new-session -s project
149+
150+
# 모니터링 전용 서버 (다른 설정 파일 사용)
151+
tmux -L monitor -f ~/.config/tmux/monitor.conf new-session -s logs
152+
```

0 commit comments

Comments
 (0)