llama-server router mode 사용 (feat. Gemini)

Local LLM 시리즈

  1. (Local LLM) Ollama 시작하기
  2. Codex 와 Local LLM 연결하기
  3. llama-server 에서 router mode 사용하기

llama-server가 라우터 모드(Router Mode)로 동작할 때, 클라이언트가 복잡한 .gguf 전체 파일명 대신 모델이름으로 모델을 지정하게 만드는 방법은 크게 두 가지가 있다.

  • --models-preset
  • --models-dir

현재 llama-server가 업데이트되면서 가장 권장되는 정석적인 방법은 TOML(ini) 설정 파일을 사용하는 것이다.


정석: --models-preset (INI 설정 파일) 사용하기

가장 깔끔하고 확실한 방법입니다. 라우터 모드를 켤 때 --models-preset 플래그를 사용하여 각 GGUF 파일에 원하는 ID(Alias)를 매핑하는 models.ini 파일을 지정하는 방식입니다.

① models.ini 파일 작성

원하는 경로에 설정 파일을 만들고, 대괄호 [모델명] 안에 클라이언트에서 호출시 사용할 Alias로 모델명를 적어준 뒤 내부에서 실제 model 경로를 지정한다.

1
2
3
4
5
6
7
8
9
[gemma-4]
model = /home/user/models/gemma-4-26b-it-q4_k_m.gguf
n_gpu_layers = 999
n_ctx = 8192

[qwen-coder]
model = /home/user/models/qwen3-coder-7b-instruct-q8_0.gguf
n_gpu_layers = 999
n_ctx = 16384

② 라우터 모드 llama-server 실행

서버 실행시 --models-preset 으로 프리셋 설정 파일을 지정한다.

1
./llama-server --models-preset ./models.ini --port 8080

③ 클라이언트 호출

현재 제공되는 모델

1
curl http://localhost:8080/v1/models

이제 OpenAI 호환 API나 클라이언트(파이썬, curl, Open WebUI 등)에서 모델 이름으로 지정한 Alias를 지정해 호출한다.

1
2
3
4
5
6
7
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gemma-4",
"messages": [{"role": "user", "content": "llama-server 의 라우터 모드를 한 문장으로 설명해줘."}]
}'

모델 qwen-coder 호출

1
2
3
4
5
6
7
8
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-coder",
"messages": [
{"role": "user", "content": "csv 파일을 읽는 파이썬 함수를 작성해줘."}
]
}'

구성 예시

동일한 장비(VRAM) 안에서 가볍게 서빙할 작은 모델과 대형 모델의 리소스를 차등 분배하여 작성한 프리셋 예시입니다.

프리셋 설정

llamaserver_preset.toml 같은 텍스트 파일에 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 전역 설정 필드 (필요시 최상단 배치)
version = 1

[qwen-7b-ins]
model = "/home/user/models/Qwen2.5-7B-Instruct-Q8_0.gguf"
ctx-size = 16384
n-gpu-layers = 99
flash-attn = 1
temp = 0.7
top-p = 0.95

[gemma-27b-heavy]
model = "/home/user/models/gemma-2-27b-it-Q4_K_M.gguf"
ctx-size = 8192
n-gpu-layers = 32 # 3080 Ti / 4060 등 VRAM 제약 시 일부만 GPU 이관
threads = 8 # CPU로 남은 레이어 연산을 위한 스레드 할당
mlock = 1 # 시스템 스왑 방지하여 레이턴시 저하 방어
temp = 0.3
min-p = 0.05


서버 시작

--models-preset 옵션에 프리셋 설정 파일을 지정한다.

1
2
3
4
5
6
7
8
9
10
11
12
$ llama-server --models-preset llamaserver_preset.toml --port 8001 --host 0.0.0.0
0.00.110.622 I log_info: verbosity = 3 (adjust with the `-lv N` CLI arg)
0.00.110.649 I system_info: n_threads = 8 (n_threads_batch = 8) / 16 | CUDA : ARCHS = 860 | USE_GRAPHS = 1 | PEER_MAX_BATCH_SIZE = 128 | CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | BMI2 = 1 | LLAMAFILE = 1 | OPENMP = 1 | REPACK = 1 |
0.00.110.650 I srv main: n_parallel is set to auto, using n_parallel = 4 and kv_unified = true
0.00.110.658 I srv init: running without SSL
0.00.110.676 I srv init: using 15 threads for HTTP server
0.00.111.579 I srv load_models: Loaded 0 cached model presets
0.00.111.743 I srv load_models: Loaded 2 custom model presets from llamaserver_preset.toml
0.00.111.769 I srv operator(): Available models (2) (*: custom preset)
0.00.111.769 I srv operator(): * g4coder
0.00.111.770 I srv operator(): * gemma4-26b
0.00.111.836 I srv main: starting router server, no model will be loaded in this process

확인

llama-server 의 로그는 journalctl 명령으로 확인 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
3.19.587.902 I srv  ensure_model: waiting until model name=gemma4-26b is fully loaded...
[50679] 0.00.032.099 I log_info: verbosity = 3 (adjust with the `-lv N` CLI arg)
[50679] 0.00.032.100 I device_info:
[50679] 0.00.170.204 I - CUDA0 : NVIDIA GeForce RTX 3080 Ti (11910 MiB, 11635 MiB free)
[50679] 0.00.170.209 I - CPU : AMD Ryzen 7 5800X3D 8-Core Processor (62168 MiB, 62168 MiB free)
[50679] 0.00.170.240 I system_info: n_threads = 8 (n_threads_batch = 8) / 16 | CUDA : ARCHS = 860 | USE_GRAPHS = 1 | PEER_MAX_BATCH_SIZE = 128 | CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | BMI2 = 1 | LLAMAFILE = 1 | OPENMP = 1 | REPACK = 1 |
[50679] 0.00.170.242 I srv main: n_parallel is set to auto, using n_parallel = 4 and kv_unified = true
[50679] 0.00.170.254 I srv init: running without SSL
[50679] 0.00.170.272 I srv init: using 15 threads for HTTP server
[50679] 0.00.170.361 I srv start: binding port with default address family
[50679] 0.00.171.553 I srv main: loading model
[50679] 0.00.171.557 I srv load_model: loading model '/home/Models/gemma-4-26B-A4B-it-UD-Q5_K_S.gguf'

모델 정보

1
curl http://localhost:8080/v1/models

다음 같은 json 출력을 얻는다

1
{"data":[{"id":"g4coder","aliases":[],"tags":[],"object":"model","owned_by":"llamacpp","created":1780772059,"status":{"value":"unloaded","args":["/home/qkboo/.local/bin/llama-server","--host","127.0.0.1","--port","0","--repeat-penalty","1.1","--temperature","0.1","--top-k","64","--top-p","0.1","--alias","g4coder","--ctx-size","65536","--model","/home/qkboo/Models/unsloth/gemma-4-26B-A4B-it-UD-Q5_K_S.gguf","--n-gpu-layers","-1"],"preset":"[g4coder]\nrepeat-penalty = 1.1\ntemperature = 0.1\ntop-k = 64\ntop-p = 0.1\nctx-size = 65536\nmodel = /home/qkboo/Models/unsloth/gemma-4-26B-A4B-it-UD-Q5_K_S.gguf\nn-gpu-layers = -1\n\n"},"architecture":{"input_modalities":["text"],"output_modalities":["text"]}},{"id":"gemma4-26b","aliases":[],"tags":[],"object":"model","owned_by":"llamacpp","created":1780772059,"status":{"value":"unloaded","args":["/home/qkboo/.local/bin/llama-server","--host","127.0.0.1","--port","0","--repeat-penalty","1.1","--temperature","1.0","--top-k","64","--top-p","0.95","--alias","gemma4-26b","--ctx-size","12288","--model","/home/quboo/Models/unsloth/gemma-4-26B-A4B-it-UD-Q5_K_S.gguf","--n-gpu-layers","-1"],"preset":"[gemma4-26b]\nrepeat-penalty = 1.1\ntemperature = 1.0\ntop-k = 64\ntop-p = 0.95\nctx-size = 12288\nmodel = /home/quboo/Models/unsloth/gemma-4-26B-A4B-it-UD-Q5_K_S.gguf\nn-gpu-layers = -1\n\n"},"architecture":{"input_modalities":["text"],"output_modalities":["text"]}}],"object":"list"}

llama-serrver 주요 파라미터

1. 모델 구성 및 메모리 맵핑 (Model & Memory)

파라미터명 설명
model (또는 m) 로컬 시스템에 저장된 GGUF 모델 파일의 절대 경로를 지정합니다.
hf Hugging Face 저장소에서 모델을 직접 지정할 때 사용합니다. (예: ggml-org/Qwen2.5-7B-Instruct-GGUF)
mmap Memory-map 사용 여부 (1 또는 0). 활성화 시 모델 로드가 빨라지지만 OS 페이지 아웃이 발생할 수 있습니다.
mlock 모델을 RAM에 강제로 잠금 처리하여 스왑(Swap) 영역으로 빠지는 것을 방지합니다. (1 or 0)

2. 하드웨어 가속 및 연산 제어 (Hardware Allocation)

파라미터명 설명
n-gpu-layers (또는 ngl) GPU로 오프로드할 레이어 수입니다. VRAM 용량에 맞춰 조절하며, 전체 레이어를 올리려면 대개 99 같은 큰 값을 지정합니다.
main-gpu (또는 mg) 멀티 GPU 환경에서 기본 가속 및 중간 연산 결과(KV)를 처리할 메인 GPU 인덱스(0, 1 등)를 지정합니다.
split-mode (또는 sm) 멀티 GPU 분할 방식을 정의합니다. (none, layer, row, tensor)
threads (또는 t) GPU에 올라가지 않고 CPU 영역에 남은 레이어를 연산할 때 사용할 쓰레드 수입니다.
threads-batch (또는 tb) 프롬프트 배치 가공 시 사용할 CPU 쓰레드 수입니다. (일반적으로 threads와 동일하게 지정)

3. 컨텍스트 및 배치 관리 (Context & Batching)

파라미터명 설명
ctx-size (또는 c) 프롬프트 및 컨텍스트 윈도우 크기를 토큰 단위로 지정합니다. (기본값 0 시 모델 메타데이터값 추종)
batch-size (또는 b) 텍스트 처리를 위한 논리적 최대 배치 크기입니다. (기본값 2048)
ubatch-size (또는 ub) 물리적 최대 배치 크기로, 청크 단위 연산 크기를 제어합니다. (기본값 512)
flash-attn (또는 fa) Flash Attention 활성화 여부입니다. 지원하는 아키텍처에서 연산 속도와 VRAM 절약에 유용합니다.

4. 추론 및 샘플링 파라미터 (Sampling Parameters)

⚠️ 주의: llama.cpp 버전 및 클라이언트 프레임워크 연동에 따라 일부 샘플링 파라미터는 프리셋 파일에 직접 선언하기보다 클라이언트 요청(API Payload) 단에서 동적으로 전달하는 것이 구동 안정성에 더 유리할 수 있습니다.

파라미터명 설명
temp 생성 텍스트의 다양성(확률 분포 평탄화)을 조절하는 온도 값입니다.
top-p 누적 확률 분포 상위 P 범위 내의 토큰들만 후보군으로 압축합니다.
top-k 확률이 가장 높은 상위 K개의 토큰으로 후보군을 제한합니다.
min-p 가장 유력한 토큰 확률 대비 최소 임계치 비율 이하인 토큰을 배제합니다.
predict (또는 n) 한 번의 요청으로 모델이 생성할 최대 토큰 수를 지정합니다. (-1 지정 시 무한대 생성)

Tmux Plugins 2

Tmux 시리즈:

  1. Tmux Start (202605)
  2. Tmux Cheatsheet (202605)
  3. Tmux Plugins (202605)
  4. Tmux Plugins2

tmux-sensible

tmux-sensible은 tmux 사용자라면 거의 필수적으로 설치하는 최우선 플러그인입니다. 리눅스 커뮤니티의 거장인 Tim Pope가 개발한 것으로, “tmux의 기본 설정(Default)이 너무 보수적이고 불편하니, 누구나 동의할 만한 상식적인(Sensible) 옵션들로 기본값을 바꾸자”라는 목적으로 만들어졌습니다.

WSL(Ubuntu 24.04)과 원격 서버(Ubuntu 26.04)를 오가며 Windows Terminal로 작업하시는 사용자님의 환경에서, 이 플러그인이 왜 중요한지 핵심 역할과 미사용 시 불편한 점을 정리해 드립니다.


1. tmux-sensible이 자동으로 잡아주는 핵심 역할

이 플러그인을 설치하면 ~/.tmux.conf에 복잡한 코드를 일일이 적지 않아도 다음과 같은 강력한 기본 설정들이 적용됩니다.

  • 키 입력 지연 시간 제거 (escape-time 0): Vim/Neovim을 쓸 때 Esc 키를 누르면 즉시 모드가 바뀌도록 지연 시간을 없애줍니다.
  • 히스토리 버퍼 대폭 확장 (history-limit 50000): 터미널 로그를 위로 스크롤해서 볼 수 있는 줄 수를 기본 2,000줄에서 50,000줄로 대폭 늘려줍니다.
  • 256화면 색상 및 True Color 활성화: 윈도우 터미널 환경에서 현대적인 화려한 테마(NeoVim 내부 테마, 로고 등)가 깨지지 않고 정확한 색상으로 출력되도록 환경 변수를 잡아줍니다.
  • 단축키 반복 시간 최적화 (repeat-time 600): 윈도우나 팬 크기를 조절할 때 단축키를 너무 연속으로 누르지 않아도 부드럽게 작동하도록 조절합니다.

2. 이 플러그인을 쓰지 않을 때 발생하는 치명적인 불편함

만약 tmux-sensible 없이 순정 상태의 tmux를 사용하면 다음과 같은 짜증 나는 상황들을 겪게 됩니다.

① Vim 사용 시 Esc 키 지연 현상 (가장 고통스러움)

순정 tmux는 Esc 키가 입력된 후 0.5초(500ms) 동안 다음 키가 들어오는지 기다립니다. 이 때문에 Vim에서 수정 모드를 빠져나오려고 Esc를 누른 뒤 바로 방향키를 누르면, 모드가 풀리는 게 아니라 엉뚱한 명령 시퀀스로 인식되어 코드가 뒤죽박죽 꼬여버립니다.

② 윈도우 터미널에서 빔(Vim) 테마 색상 깨짐

최신 윈도우 터미널은 수백만 가지 색상(True Color)을 표현할 수 있습니다. 하지만 순정 tmux는 구시대적인 8색/16색 모드로 시작하는 경우가 많아, 고급스러운 개발자용 빔 테마를 켜도 색상이 칙칙하게 뭉개지거나 아예 가독성이 떨어지는 색으로 변해버립니다.

③ 조금만 빌드 로그가 길어져도 위쪽 내용이 잘림

앞서 LLM 관련 컴파일(llama.cpp 빌드 등)이나 대용량 로그를 출력할 때, 순정 tmux는 기본 버퍼가 2,000줄밖에 되지 않습니다. 컴파일 도중 에러가 나서 위로 스크롤(Ctrl + B 후 [)을 해보면, 에러의 시작점이 이미 잘려 나가서 정작 중요한 에러 원인을 파악하지 못하는 상황이 발생합니다.

④ Ctrl + B 단축키 연속 입력의 피로감

순정 상태에서는 윈도우를 넘나들거나 팬을 다룰 때, 리눅스가 단축키 대기 시간을 너무 타이트하게 잡거나 반대로 너무 길게 잡아서 명령이 씹히는 느낌을 자주 받게 됩니다.


💡 요약 및 추천

tmux-sensible은 특이하고 기상천외한 기능을 추가해 주는 플러그인이 아닙니다. 단지 “당연히 이래야지” 싶은 현대적인 개발 환경 표준을 명령어 한 줄로 세팅해 주는 패키지입니다.


현재 경로의 디렉터리 트리 표시에 가장 널리 사용되는 tmux-sidebar 플러그인

.tmux.conf 에 등록하고 설치하면 된다.

1
set -g @plugin 'tmux-plugins/tmux-sidebar

기본 단축키는 다음과 같습니다

  • C + Tab : 디렉터리 트리 사이드바를 열거나 닫습니다(토글). 커서는 원래 패널에 유지됩니다.
  • C + Backspace : 사이드바를 열거나 닫으며, 커서를 사이드바로 이동합니다.
  • C + x : 현재 tmux pane 을 종료로 나갈 수 있다.

사이드바를 켜면 현재 터미널 왼쪽에 트리 형태의 디렉토리 구조를 보여줍니다.


tmux2k

상태바를 고급스럽게 표현할 수 있다.

  1. 설치

  2. tmux2k는 아이콘을 표현하기 위해 Nerd Font(너드 폰트)가 필수입니다. 일반 폰트를 사용하면 아이콘이 깨지거나 빈 네모 모양으로 표시됩니다.

Windows 터미널 (WSL/PowerShell 등) 사용 시:

WSL 설정 -> 사용중인 프로필 -> 모양 -> 글꼴에서 Nerd Font 지정

  • 설정 (Ctrl + Shift + ,) -> 사용 중인 프로필(Ubuntu 등) -> 대형 항목 또는 모양 -> 글꼴에서 설치한 Nerd Font 선택 후 저장.

우분투

1
2
3
4
5
wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.4.0/JetBrainsMono.zip

mkdir .fonts
cd .fonts
unzip ../JetBrainsMono.zip

폰트 캐시

1
2
3
fc-cache -fv
....
/home/user/.fonts: caching, new cache contents: 96 fonts, 0 dirs
1
set -g @plugin '2kabhishek/tmux2k'

아이콘 문제

tmux2k 사용 시 아이콘이 깨지는 현상은 주로 터미널 글꼴, UTF-8 로케일 설정, 터미널 환경 변수($TERM) 문제로 발생한다.

1
2
~$ echo $LANG
C.UTF-8

Tmux Start (202605)

Tmux 시리즈:

  1. Tmux Start (202605)
  2. Tmux Cheatsheet (202605)
  3. Tmux Plugins (202605)

이 내용은 tmux 2.x, 3.x 에서 사용 가능하다.

2026-05-29: 내용 문맥 조정, 설치 부분 삭제.
- OLD Tmux Start(20170504)
2017-07-10: tmux-continum 추가

Tmux는 terminal multiplexer로 서버에 여러 프로그램을 세션에 저장하고, 다른 작업 혹은 연결을 끊었다 다시 접속해서 세션을 열어 작업을 이어갈 수 있다.

[그림. Tmux 실행 모습 (tmux.github.io)]

설치 관련 (OLD machines)

최신 리눅스는 대부분 내장으로 설치된 듯 하다: WSL, Ubuntu 24.04/26.04 …

  • Ubuntu 14.04, Raspbian Jessie, Armbian 등에서 tmux가 1.8, 1.9 버전이 제공
  • Ubuntu 15, 16 Xenivior 버전은 Tmux 2.1
  • Old 버전 Ubuntu 14.04, Raspbian 등에서 tmux가 1.8, 1.9 버전이 제공되는데 package manager 같은 기능을 사용할 수 없다. 소스로 빌드해서 사용할 수 있다.
  • Ubuntu 14.04 desktop, orangepi plus, raspberry pi jessie 초기 버전은 빌드 필요

시작

tmux 명령으로 시작할 수 있다.

tmux 를 시작하면 하나의 세션에 하나의 윈도우가 만들어 진다.

1
2
$ tmux                   # 세션을 시작하고 참가한다.
$ tmux new -s foo # 세션 foo를 시작하고 참가한다

세션에 참가하면 하나 혹은 그 이상의 윈도우에서 Pane을 배치해 사용할 수 있다.


[그림. Tmux window layout]


세션 연결

세션은 하나 혹은 그 이상 만들고 attach 명령으로 세션에 참가할 수 있다.

1
2
3
4
$ tmux new -s foo        # 세션 foo를 시작
$ tmux ls # 세션 목록을 출력한다.
0: 1 windows (created Fri May 12 10:26:00 2017) [80x24] (attached)
foo: 1 windows (created Fri May 12 10:34:18 2017) [80x24]

터미널에서 세션에 참가하려면 attach 명령과 대상 세션을 지정해 준다. 대상 세션은 tmux ls 명령에 표시되는 세션번호 혹은 세션이름을 지정한다.

1
2
3
$ tmux attach
$ tmux attach -t 0 # 세션 0번에 참여한다
$ tmux attach -t foo # 세션 foo에 참여한다.

세션을 완전히 종료 시키려면, tmux 세션에서 명령모드 C-: 에서 kill-session 명령을 실행한다.
혹은 다른 터미널에서 세션번호 혹은 세션 이름으로 종료한다.

1
$ tmux kill-session -t 3   # 세션번호 3을 종료한다.

Control와 Meta key

Tmux 세션 시작후 Prefix key 를 통해 세션, 윈도우와 tmux 내장 명령을 실행할 수 있다.

즉, Prefix key로 Session, Window, Pane 관련 명령을 키로 조합해 사용한다.

기본 Prefix key는 Control+b key고 옵션으로 사용하는 Meta key는 Alt 키 이다.

여기서 Prefix key는 C와 조합으로 표기하고, Meta key인 Alt는 M으로 표기한다.

윈도우 명령 control, meta 키 조합과 병행해 윈도우에서 명령모드를 사용할 수 있다.

명령모드는 C-: 키로 시작하고, 명령모드에서 명령 자동 완성 이 지원된다.


[그림. Window command mode]


Pane 다루기

윈도우는 수직/수평으로 구획을 나눌수 있다. C-“ 키로 현재 Pane 아래에 수평으로 새 Pane을 나눈다. 그리고 **C-%**키로 수직으로 새 Pane을 나눌 수 있다.


[그림. Tmux Window Pane]

  • C-q : pane 번호를 표시하고 번호를 눌러서 이동
  • C-o : pane을 순서대로 이동
  • C-방향키 : 해당 방향으로 이동
  • C-M-방향키 : 해당 방향으로 크기 조절
  • C-M-1~5 : 몇 가지 미리 설정된 레이아웃을 고를 수 있고, prefix space로 이 레이아웃을 순서대로 - 돌아가며 선택 가능
  • C-z : 특정화면만 확대하기 다시 예전 Panes상태로 돌아오기

Pane을 지우려면 C-x 키로 종료 혹은 터미널에서 exit로 터미널을 종료한다


Window 다루기

윈도우는 명령모드에서 new-window 혹은 C-c 키로 새 윈도우를 추가할 수 있다.


[그림. new Window ]

윈도우 목록은 C-w로 목록을 표시, 방향키로 윈도우 선택해 이동할 수 있다.

또한 윈도우 번호에 따라 단축키 C-0,1,2…9를 사용해 윈도우 사이의 이동 가능.

  • C-n, C-p : 다음 윈도우, 이전 윈도우로 이동
  • C-l : 직전 사용하던 윈도우로 이동
  • C-w : 윈도우 리스트를 띄우고 선택
  • C-, : 윈도우 이름 바꾸기

세션 사용중에 세션을 빠져 나오려면 C-d 로 Tmux 를 detach 할 수 있다.

detach는 명령모드 C-:에서 detach 명령을 사용할 수 있다.


복사와 스크롤

Tmux 터미널 화면 버퍼는 한 화면만 표시가 가능하다.

이전 화면 내용을 보려면 스크롤 기능을 켜야 한다. C+[ 로 스크롤 켜면, 우측상단에 페이지 표시가 나타난다.

키보드 방향키나 Page Up/Down키로 스크롤이 가능하다.


설정 사용

Tmux 의 환경 파일은 tmux 설정을 위힌 default 파일이 존재하지 않는다. 그래서 사용자가 별도의 설정파일에 작성해서 사용하면 된다.

보통 사용자 홈디렉토리에 .tmux.conf 파일에 tmux에 대한 설정을 명시할 수 있다.

설정 탑재:

  1. tmux 세션 사용중, 설정 재탑재

현재 사용중인 세션에서 C+r 로 재탑재가 가능하다.

1
C-r : 설정 파일을 새로고침합니다 
  1. tmux source 사용

변경한 설정을 적용하려면 터미널에서 다음 명령을 사용한다.

1
tmux source ~/.tmux.conf

현재 설정 추출과 백업:

tmux 기본 설정을 백업 혹은 확인하려면 tmux show 명령으로 확인이 가능하다.

1
tmux show -g

현재 tmux에 설정된 값을 백업:

1
tmux show -g | sed 's/^/set-option -g /' > ~/.tmux/tmux.current.conf

Prefix key 조합 변경

Prefix 키를 Control + a 키 조합이 편하다. 설정파일에 키 조합을 지정한다.

1
2
3
4
5
#Control+a에 'prefix' 연결
set -g prefix C-a
#send-prefix를 Control+a에 전달
bind C-a send-prefix
unbind C-b

설정을 다시 탑재하면 prefix는 C-a 로 재배치된다.

관리자들은 Capslock키를 Control 키도 선호한다.


참고

  1. OLD Tmux 시작
  2. OLD Tmux cheatsheet

Tmux Plugins (202605)

Tmux 시리즈:

  1. Tmux Start (202605)
  2. Tmux Cheatsheet (202605)
  3. Tmux Plugins (202605)

수정

2026-06-07: resurrect 무한 루프 내용 추가

Plugin manager

Tmux Pluin Manager 를 설치하고, tmux 기능을 확장할 수 있다.

tpm 설치

먼저 사용자 홈 디렉토리에 저장한다.

1
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

다음 설정을 tmux.conf 에 저장한다.

1
2
3
4
5
6
7
8
9
# List of plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'

# other plugins ...

# Initialize TMUX plugin manager
# (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'

그리고 tmux 환경설정을 다시 탑재한다.

1
tmux source ~/.tmux.conf

plugin 설치와 키 바인딩

새 플러그인을 .tmux.conf 에 set -g @plugin 로 입력한다.

  1. 플러그인 설치를 위해서 C-I (대문자) 를 실행
  2. 플러그인 업그레이드를 위해서 C-U (대문자) 를 실행
  3. 플러그인 삭제:
    • .tmux.conf 에서 플러그인 삭제
    • C-M-u (소문자)

tpm 으로 해당 플러그인은 ~/.tmux/plugins/ 디렉토리에 패치된다.


주요 plugins

https://github.com/tmux-plugins/list

몇가지 플러그인을 설치해서 사용해 보자

tmux-sidebar

tmux 화면에 sidebar 로 tree 형식의 디렉토리 구조를 보여준다.

  1. .tmux.conf 에 플러그인을 추가한다.
1
set -g @plugin 'tmux-plugins/tmux-sidebar'
  1. tmux source 나 C-r 로 설정을 재 탑재한다.

  2. C-I 로 플러그인 설치를 시작한다.

1
2
3
4
5
6
7
8
9
Already installed "tpm"
Installing "tmux-sensible"
"tmux-sensible" download success
Installing "tmux-sidebar"
"tmux-sidebar" download success

TMUX environment reloaded.

Done, press ESCAPE to continue.
  1. side-bar 키 바인딩
  • prefix + Tab - toggle sidebar with a directory tree
  • prefix + Backspace - toggle sidebar and move cursor to it (focus it)

plugin 삭제

  1. .tmux.conf 에서 해당 플러그인을 삭제한다.
  2. C-M-u 로 플러그인을 삭제한다.

여기서는 tmux-cpu 를 삭제하고 있다.

1
2
3
4
5
6
Removing "tmux-cpu"
"tmux-cpu" clean success

TMUX environment reloaded.

Done, press ESCAPE to continue.

Tmux-Resurrection

_tmux-resurrect_는 tmux 세션을 백업/복구 할 수 있는 플러그인이다. tmux.conf에 다음을 추가

1
set -g @plugin 'tmux-plugins/tmux-resurrect'

플러그인 설치를 위해서 C-I 를 실행하면 설치를 시작한다.

Resurrection 플러그인으로 백업/복구하는 키는 다음 같이 지정되어 있다:

  • C-s : save
  • C-r : restore

Tmux-continuum

tmux-continuum은 tmux-resurrect 플러그인과 연동하여 tmux 세션 상태를 주기적으로 자동 저장하고, 시스템 부팅 시 복원해주는 플러그인입니다.

tmux-continuum 의 주요 기능은:

  • tmux 환경을 15분 마다 자동 저장
  • 컴퓨터/서버 시작시 tmux 자동 시작 가능
  • tmux 시작시 자동 복구 가능
  • tmux 1.9 이상, bash, tmux-resurrect plugin

설치

  1. 설치는 .tmux.conf 파일에 mux-resurrect 와 tmux-continuum 플러그인을 추가:
1
2
3
4
5
6
7
8
9
10
11
12
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

# (continuum) tmux 시작 시 마지막 세션 자동 복원
set -g @continuum-restore 'on'

# (continuum) 자동 저장 간격 변경 (기본값: 15분)
set -g @continuum-save-interval '15'

# (continuum) continuum 상태표시
set -g status-right 'Continuum status: #{continuum_status}'
  1. tmux source 나 C-r 로 설정을 재 탑재한다.

  2. C-I 로 플러그인 설치를 시작한다.

1
2
3
4
5
6
7
8
9
10
11
Already installed "tpm"
Already installed "tmux-sensible"
Already installed "tmux-sidebar"
Installing "tmux-resurrect"
"tmux-resurrect" download success
Installing "tmux-continuum"
"tmux-continuum" download success

TMUX environment reloaded.

Done, press ESCAPE to continue

이제부터 15분 마다 자동 저장하고 서버를 재시작한 후에 tmux를 다시 시작하면 저장한 환경을 자동으로 복구해 준다.

  1. 키 바인딩
  • 세션 수동 저장: Ctrl + b 누른 후 Ctrl + s (Resurrect 기능)
  • 세션 수동 복원: Ctrl + b 누른 후 Ctrl + r (Resurrect 기능)

tmux 세션을 모두 나와서 tmux 서버를 모두 kill-session 같은 명령으로 종료시킨후 tmux를 다시 시작하면 .tmux/resurrect 에 저장된 마지막 세션이 복구되는 것을 확인할 수 있다.


tmux 무한 exited 문제

tmux-resurrect와 continuum은 가끔 문제를 일으킨다.

재시작 등의 이유로 이전 저장한 세션을 탑재중 무한 exited 로 종료되는 상황이 그것이다.

예를 들어 tmux2k 설정중 시스템 locale 을 다시 설정하게 된 후 tmux 가 exited 되는 문제가 발생했다.

세션을 모두 빠져나간다

1
$ tmux kill-server # 다른 터미널에서 실행

방법1:

.tmux.conf 에서 set -g @continuum-restore ‘on’을 #으로 주석 처리

tmux 실행 후 정상 작동 확인후 안되면 방법2로 모든 세션을 초기화 한다.

방법2. continuum 세션 삭제

continuum 의 세션은 백업 파일이 꼬여서 그런것 같다.

tmux-resurrect와 continuum은 세션 정보를 특정 디렉토리에 텍스트 파일로 저장하고 있다.

기본 저장 위치는 아래와 같다.

1
2
3
4
5
$ ls -l .local/share/tmux/resurrect/
total 4
lrwxrwxrwx 1 user user 34 5월 29 21:47 last -> tmux_resurrect_20260529T214713.txt
-rw-r--r-- 1 user user 239 5월 29 21:36 tmux_resurrect_20260529T213616.txt
-rw-rw-r-- 1 user user 0 5월 29 21:47 tmux_resurrect_20260529T214713.txt

기존에 저장된 백업 데이터를 삭제(초기화)한다.

1
rm -rf ~/.local/share/tmux/resurrect/*.txt

해당 세션 정보 백업 파일을 삭제후 tmux 를 시작하면 깨끗하게 다시 시작된다.


CLI 로 플러그인 관리

https://github.com/tmux-plugins/tpm/blob/master/docs/managing_plugins_via_cmd_line.md

Rsync에서 update, delete 사용

폴더 동기화 하기

여기도 확인.

https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories

rsync 로 source 와 local folder 를 동기화 하고자 한다.

이런 상황을 destination 에 동기화해서 적용하는 것이다.

  1. --dry-run : 전송 전에 전송할 목록을 확인한다.

  2. --update : “”

목차

  1. 전체 동기화
  2. local 기준 동기화
  3. checksum 사용



1. 전체 동기화

  1. source 모든 파일
  2. source 새 파일 추가
  3. source 수정한 파일
  4. source 삭제된 파일

source 모든 파일

source 폴더는 다음 같다.

1
2
3
source:~/$ mkdir tst
source:~/$ cd test/
source:~/test$ touch a.txt b.txt
1
2
3
4
5
6
~$ rsync -avzh --dry-run /source/ /local/
receiving incremental file list
./
a.txt
b.txt

동기화를 실행한다.

1
2
3
4
5
6
7
8
~$(3.11.7)qkboo:~$ rsync -avzh --update --delete --e 'ssh -p 2020' qkboo@220.121.133.119:~/Q
kboo/test/ test/
receiving incremental file list
deleting c.txt
./

sent 51 bytes received 96 bytes 294.00 bytes/sec
total size is 0 speedup is 0.00

source 새 파일 추가

qkboo@homebook:~/Qkboo/test$ touch c.txt

source 파일 수정 상황

1
qkboo@homebook:~/Qkboo/test$ vi c.txt

source 폴더에 삭제 발생

1
qkboo@homebook:~/Qkboo/test$ rm c.txt

dry-run 을 실행해 확인하면 --update --delete 를 사용하면 로컬 파일이 삭제 된다.

1
2
3
4
5
6
7
~$ rsync -avzh --dry-run --update --delete --e 'ssh -p 2020' qkboo@220.121.133.119:~/Qkboo/test/ test/
receiving incremental file list
deleting c.txt
./

sent 51 bytes received 96 bytes 294.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

동기화를 실행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
~$(3.11.7)qkboo:~$ rsync -avzh --update --delete --e 'ssh -p 2020' qkboo@220.121.133.119:~/Q
kboo/test/ test/
receiving incremental file list
deleting c.txt
./

sent 51 bytes received 96 bytes 294.00 bytes/sec
total size is 0 speedup is 0.00

(3.11.7)qkboo:~$ ll test/
total 8
drwxrwxr-x 2 qkboo qkboo 4096 Jul 20 09:37 ./
drwxr-xr-x 39 qkboo qkboo 4096 Jul 20 09:34 ../
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 a.txt
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 b.txt

로컬에서 작업이 발생하는 경우

rsync 시 source/ 와 source/* 의 결과 차이가 발생한다.

로컬에 새 파일이 생기는 경우

source 와 destination 폴더 동기화 된 상태에서 destination 폴더에 새 파일이 추가된다.

1
2
3
4
5
6
7
(3.11.7)qkboo:~$ touch test/local.txt; ll test/
total 8
drwxrwxr-x 2 qkboo qkboo 4096 Jul 20 09:59 ./
drwxr-xr-x 39 qkboo qkboo 4096 Jul 20 09:34 ../
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 a.txt
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 b.txt
-rw-r--r-- 1 qkboo qkboo 0 Jul 20 09:59 local.txt

source 폴더에 / 구분자만 사용해서 확인해 본다.

dry-run 을 실행해 확인하면 --update --delete 를 사용하면 로컬 파일이 삭제 된다.

1
2
3
4
5
6
7
8
(3.11.7)qkboo:~$ rsync -avzh --update --delete --dry-run --e 'ssh -p 2020' qkboo@220.121.1
33.119:~/Qkboo/test/ test/
receiving incremental file list
deleting local.txt
./

sent 51 bytes received 96 bytes 98.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

--ignore-existing 도 삭제가 발생한다.

1
2
3
4
5
6
7
~$ rsync -avzh --update --delete --ignore-existing --dry-run --e 'ssh -p 2020' qkboo@220.121.133.119:~/Qkboo/test/ test/
receiving incremental file list
deleting local.txt
./

sent 51 bytes received 96 bytes 98.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

--update 만 사용하면 로컬에 변경있는 파일은 무시된다.

1
2
3
4
5
6
7
~$ rsync -avzh --update --dry-run --e 'ssh -p 2020' qkboo@220.121.133.119:~/
Qkboo/test/ test/
receiving incremental file list
./

sent 51 bytes received 96 bytes 294.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

source/* 로 사용하면 --update --delete 를 사용해도 로컬 파일이 무시된다.

1
2
3
4
5
6
7
8
(3.11.7)qkboo:~$ rsync -avzh --update --delete --dry-run --e 'ssh -p 2020' qkboo@220.121.1
33.119:~/Qkboo/test/ test/
receiving incremental file list
deleting local.txt
./

sent 51 bytes received 96 bytes 98.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

source 와 local 모두 새 파일 생기면

1
source/ $ touch d.txt

source/* 로 사용하면 --update --delete 로 새 파일을 받는다.

1
2
3
4
5
6
(3.11.7)qkboo:~$ rsync -avzh --update --delete --dry-run --e 'ssh -p 2020' qkboo@220.121.133.119:~/Qkboo/test/* test/
receiving incremental file list
d.txt

sent 51 bytes received 96 bytes 294.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

local 에도 새 파일이 생기면

1
local/ $ touch test/local2.txt

source/* 로 사용하고 --update --delete 로 새 파일을 받고 로컬은 유지된다.

1
2
3
4
5
6
local:~/ $ rsync -avzh --update --delete --dry-run --e 'ssh -p 2020' qkboo@220.121.133.119:~/Qkboo/test/* test/
receiving incremental file list
d.txt

sent 51 bytes received 96 bytes 98.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)
ll test/
1
2
3
4
5
6
7
8
total 8
drwxrwxr-x 2 qkboo qkboo 4096 Jul 20 10:46 ./
drwxr-xr-x 39 qkboo qkboo 4096 Jul 20 09:34 ../
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 a.txt
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 b.txt
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 10:40 d.txt
-rw-r--r-- 1 qkboo qkboo 0 Jul 20 09:59 local.txt
-rw-r--r-- 1 qkboo qkboo 0 Jul 20 10:43 local2.txt

정리

전체 동기화 후 source,local 모두 변경이 발생

  1. local 기준으로 동기화 하려면 srouce/* 를 꼭 사용한다.
  2. 혹은 local 기준으로 동기화시 --update 만 사용한다.

source 기준으로 동기화 하려면

  1. source 기준으로 동기화 하려면 srouce/ 로 사용한다.


---

[참고] source 와 local 의 같은 파일 동시 수정되면?

양쪽 모두 파일 내용의 갱신이 발생하는 이런 경우는 가능하면 VCS 도구를 사용하자!!!

다음 같이 동기화 한 상태에서 a.txt 를 source 와 local 에서 모두 수정한다면?

ll test/
1
2
3
4
5
6
7
8
total 8
drwxrwxr-x 2 qkboo qkboo 4096 Jul 20 10:46 ./
drwxr-xr-x 39 qkboo qkboo 4096 Jul 20 09:34 ../
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 a.txt
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 09:16 b.txt
-rw-rw-r-- 1 qkboo qkboo 0 Jul 20 10:40 d.txt
-rw-r--r-- 1 qkboo qkboo 0 Jul 20 09:59 local.txt
-rw-r--r-- 1 qkboo qkboo 0 Jul 20 10:43 local2.txt

source/a.txt 에는 ‘AAA’ 문자열이 추가했고, local/a.txt 는 ‘local’ 단어로 변경했다.

단, 다음 같이 비슷한 시간대에 수정한 양쪽의 파일에는 변화가 없다.

source 의 a.txt 파일

1
2
3
$ ls -l a.txt
total 4
-rw-rw-r-- 1 qkboo qkboo 4 Jul 20 10:49 a.txt

local 의 a.txt 파일

1
2
$ ls -l a.txt
-rw-rw-r-- 1 qkboo qkboo 6 Jul 20 10:49 a.txt

변화가 없다.

1
2
3
4
5
~$ rsync -avzh --update --delete --dry-run --e 'ssh -p 2020' qkboo@220.121.133.119:~/Qkboo/test/* test/
receiving incremental file list

sent 44 bytes received 98 bytes 94.67 bytes/sec
total size is 4 speedup is 0.03 (DRY RUN)

시간과 Byte 변화가 있으면 다음 같이 갱신을 수행한다.

1
2
3
4
5
6
7
~$
local:~$ rsync -avzh --update --delete --dry-run source/test/* local/test/
receiving incremental file list
a.txt

sent 51 bytes received 100 bytes 302.00 bytes/sec
total size is 228 speedup is 1.51 (DRY RUN)

source/a.txt 에 Byte 변화가 좀 커지면 동기화가 수행된다.

qkboo@homebook:~/Qkboo/test$ ls -l a.txt
-rw-rw-r– 1 qkboo qkboo 16 Jul 20 10:56 a.txt

source/a.txt 가 local에 동기화가 되고 로컬은 source/a.txt로 교체된다.

1
2
3
4
5
6
7
~$
(3.11.7)qkboo:~$ rsync -avzh --update --delete --dry-run --e 'ssh -p 2020' qkboo@220.121.133.119:~/Qkboo/test/* test/
receiving incremental file list
a.txt

sent 51 bytes received 100 bytes 100.67 bytes/sec
total size is 16 speedup is 0.11 (DRY RUN)

양쪽 모두 갱신이 발생하는 이런 경우는 가능하면 VCS 도구를 사용하자!!!

3. checksum 사용

1
2
3
~$
local:~$ rsync -avzh --update --delete --checksum --dry-run source/test/* local/test/
receiving incremental file list

HTTPS 를 위한 Private SSL

Web server certificates 과정

Securing a web site with a server certificate 단계

  1. 비밀키를 생성한다.
  2. 비밀키로 CSR certificate siging requests 을 생성한다.
  3. CSR 을 CA 로 사인한다.
  4. 사인한 CERT 를 받고 설치한다.

1. 비밀키를 생성한다.

rsa 를 사용해 4096크기 비밀키를 생성한다.

1
2
3
4
5
# cd /etc/ssl/private 
# openssl genrsa -out my_rsa.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)

# chmod 0600 private/my_rsa.key
1
# chmod 0600 private/my_rsa.key

Public Key 생성

1
명령: openssl rsa -in [private key 파일명] -pubout -out [파일명]
1
# openssl rsa -in my_rsa.key -pubout -out my_rsa.pub 

2. Create a CSR(certificate signing request) from this key,

인증서 발급을 위한 필요한 정보를 담고 있는 인증서 신청서를 작성한다.

1
명령어 : openssl req -new -key [private key 파일명] -out [파일명]

비밀키에서 CSR 파일 작성을 요청하면 아래 내용을 묻는다.

1
# openssl req -new -sha256 -key ./my_rsa.key -out ./my_rsa.csr 
1
# openssl req -new -key private.key -out private.csr

인증서 발급을 위한 필요한 정보를 담고 있는 인증서 신청 형식 데이터 이다.

  • Country Name (국가코드) KR
  • State or Province Name (시/도의 전체이름) Seoul
  • Locality Name (시/군/구 등의 이름) Songpa-gu
  • Organization (회사이름) XXXX
  • Organization Unit (부서명) Server
  • Common Name (SSL 인증서를 설치할 서버의 Full Domain) www.xxxx.com
      • Common Name 에는 인증서를 설치할 사이트의 도메인의 이름을 넣어야 한다. (ip, port, http, https 포함불가능)

4. CA 인증한 CRT 인증서 만들기

CSR 을 CA에서 인증해 CRT 파일을 생성한다. 여기서는 비밀키와 CSR 요청서를 바탕으로 CRT 인증서를 생성한다.

1
명령어 : openssl req -x509 -days [기간] -key [private key 파일명] -in [csr 파일명] -out [파일명] -days [기간]

x509 를 이용하고 365일 사용 가능한 crt 인증서를 생성한다.

1
openssl req -x509 -days 365 -key my_rsa.key -in my_rsa.csr -out my_rsa.crt -days 365

생성한 혹은 CA에서 받은 CRT 파일은 아래 같이 확인해 볼 수 있다.

1
openssl x509 -text -in yourdomain.crt -noout

5. CRT 파일을 PEM 파일로 변환한다.

1
openssl x509 -in mycommoncrt.crt -out mycommonpem.pem -outform PEM 

[Tip] 인증서 Config 파일 (test.conf)

위에서 만들다 보면 계속 같은 내용을 써야 한다. 그래서 그 부분을 파일로 만들어 놓고 csr, crt 생성할때 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[dn]
C=KR
ST=Seoul
L=Seoul
O=COMPANY
OU=DEV
emailAddress=test@test.com
CN = testmachine

[req_ext]
subjectAltName = @alt_names

[alt_names]
IP.1 = 111.111.111.111
DNS.1 = test.com

csr 을 생성한다.

1
openssl req -new -key private.key -out private.csr -config test.conf

csr, crt 파일을 생성한다.

1
openssl req -x509 -days 365 -key private.key -in private.csr -out mycommoncrt.crt -days 365 -config test.conf

그리고 이렇게 해서 인증서를 만들었을때 subjectAltName 이 안들어간다 . 그 부분이 필요할 경우에는 이렇게 명령어를 사용하면 된다.

1
openssl req -x509 -days 365 -key private.key -in private.csr -out mycommoncrt.crt -days 365 -config test.conf -extensions req_ext

openssl 팁 몇가지

CRT 파일 확인

openssl x509 -text -noout -in <인증서파일> : 인증서 내용을 볼수 있다.

Verifying Your Keys Match

1
2
3
openssl pkey -pubout -in .\private.key | openssl sha256
openssl req -pubkey -in .\request.csr -noout | openssl sha256
openssl x509 -pubkey -in .\certificate.crt -noout | openssl sha256

NGINX 웹 서버 TLS 암호화 추가

개인키와 TLS 인증서 crt 파일을 사용한다.

1
2
$ sudo mkdir /etc/nginx/tls/private
$ mv my_rsa.key my_rsa.crt /etc/nginx/tls/private
  1. 개인 키는 /etc/nginx/tls/private/my_rsa.key 파일에 저장됩니다.
  2. 개인 키 및 CSR(인증서 서명 요청) 생성 및 CA(인증 기관)에서 인증서 TLS 인증서는
    • /etc/nginx/tls/private/example.com.crt 파일에 저장됩니다.
1
2
3
4
5
6
7
server {
listen 443 ssl;
server_name www.thinkbee.kr;
root /home/qkboo/Home/www/thinkbee.kr/;
ssl_certificate /etc/nginx/tls/private/my_rsa.crt;
ssl_certificate_key /etc/nginx/tls/private/my_rsa.key;
}

참고

  1. Howto – Install a self signed web server certificate
  2. openssl quick reference guide
  3. Openssl로 SSL 을 위한 인증서 발급하기 (HTTPS),blog
  4. Nginx - HTTPS and Certificate SSL,blog
  5. NodeJS와 Nginx 웹 서버,blog

Jupyterlab 에서 password 생성해 systemd 서비스 이용

Jupyter Lab - systemd 운영

jupyterlab 을 Itel 기반의 Ubuntu 시스템에 설치하고 시스템 서비스로 등록하는 과정.

  1. Ubuntu 18.04
  2. node.js
  3. Anaconda 2020

Restart your shell so the path changes take effect. You can now begin using pyenv.

1
exec "$SHELL"

Anaconda 배포본 설치 (Ubuntu)

우분투용 다운로드

https://www.anaconda.com/products/individual#linux

다움로드안 쉘 스크립트를 시작한다.

1
bash ~/Downloads/Anaconda3-2020.02-Linux-x86_64.sh

To control whether or not each shell session has the base environment activated or not, run conda config –set auto_activate_base False or True. To run conda from anywhere without having the base environment activated by default, use conda config –set auto_activate_base False. This only works if you have run conda init first.

Anaconda 를 설치하면 대부분의 패키지가 내장되어 있다.

설치후 최신 conda 환경 base를 갱신해 준다.

1
conda update -n base -c defaults conda

nvm으로 Node.js 설치

nvm 설치

1
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash

스크립트로 설치를 완료하면 쉘 시작시 nvm 환경을 구성하기 위해서아래 스크립이 자동으로 현재 쉘 스크립트 파일 끝에 추가된다.

만약 아래 스크립이 추가 안되면 아래 스크립트를 (~/.bash_profile, ~/.zshrc, ~/.profile, or ~/.bashrc).)에 추가한다.

1
2
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

node.js 설치

1
2
3
4
5
6
~$ nvm ls-remote
v14.0.0
v14.1.0
v14.14.0
v14.15.0 (LTS: Fermium)
v14.15.1 (Latest LTS: Fermium)

lts 최신 버전 14.0을 설치한다.

1
2
3
4
5
6
7
8
~$ nvm install --lts 14.15.1
Downloading and installing node v14.15.1...
Downloading https://nodejs.org/dist/v14.15.1/node-v14.15.1-linux-x64.tar.xz...
######################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v14.15.1 (npm v6.14.8)
Creating default alias: default -> lts/* (-> v14.15.1)

node 버전을 확인

1
2
~$ node --version
v14.15.1

Conda 에서 jupyterlab 설치

Anaconda 나 Miniconda 를 설치하고 가상환경을 하나 생성한다.

1
2
3
4
$ conda create -n tf2 jupyterlab numpy scipy matplotlib tensorflow

$ conda activate tf2
(tf2) ~$

JupyterLab 실행

가상환경에서 jupyterlab 을 외부에서 접속 가능하도록 실행하자.

1
(base) $ jupyter-lab --no-browser --ip=* --port=8888 ~/Jupyter-Notebook/

LabConfig 디렉토리

1
2
3
4
5
6
7
8
9
10
11
12
13
$ jupyter --paths
config:
/home/qkboo/.jupyter
/home/qkboo/anaconda3/envs/py3/etc/jupyter
/usr/local/etc/jupyter
/etc/jupyter
data:
/home/qkboo/.local/share/jupyter
/home/qkboo/anaconda3/envs/py3/share/jupyter
/usr/local/share/jupyter
/usr/share/jupyter
runtime:
/home/qkboo/.local/share/jupyter/runtime

JupyterLab 환경 설정

jupyter 의 config 파일을 통해서 인증과 구성을 하자.

  • jupyterlab 3.x 버전: jupyter_server_config.py
  • jupyterlab 2.x 버전: jupyter_notebook_config.py

Jupyter Lab 에서 설정 파일을 생성한다. 다음 명령으로 각각 $HOME/.jupyter/ 위치에 jupyter_server_config.py 파일이 생성된다.

1
2
(tf2)$ jupyter lab --generate-config
Writing default config to: /home/qkboo/.jupyter/jupyter_server_config.py

패스워드 사용

jupyter_notebook_config.py 설정 파일에 비밀번호를 추가하려면 비밀번호를 생성해야 한다. 아래 명령으로 생성한다.

1
2
3
4
(tf2)$ jupyter lab password
Enter password:
Verify password:
[NotebookPasswordApp] Wrote hashed password to $HOME\.jupyter\jupyter_server_config.json

jupyter_server_config.json 파일로 암호가 생성된다. 생성한 암호를 jupyter_server_config.py 파일의 c.ServerApp.password 항목에 입력해 준다

1
2
3
4
5
[jupyter_server_config.py]

c.ServerApp.password = 'sha1:*********' # 외부 접속시 사용할 비밀번호
c.ServerApp.ip = '*' # 어디서든 접속 가능
c.ServerApp.port = 8888 # 접속에 사용할 포트

Jupyter Lab 3.x 버전

1
2
3
4
5
6
7
8
9
c.ServerApp.base_url = '/notebook'
c.ServerApp.enable_mathjax = True
c.ServerApp.password = ''
c.ServerApp.ip = '*'
c.ServerApp.port = 8888
c.ServerApp.port_retries = 10
c.ServerApp.open_browser = False

c.ServerApp.tornado_settings = {"websocket_max_message_size": 400 * 1024 * 1024}

Jupyter Notebook, Jupyterlab 2.x 버전:

1
2
3
4
5
6
7
8
9
c.NotebookApp.base_url = '/notebook'
c.NotebookApp.enable_mathjax = True
c.NotebookApp.password = ''
c.NotebookApp.ip = '*'
c.NotebookApp.port = 8888
c.NotebookApp.port_retries = 10
c.NotebookApp.open_browser = False

c.NotebookApp.tornado_settings = {"websocket_max_message_size": 400 * 1024 * 1024}

systemd 구성

nodejs, jupyter lab 을 시스템 시작 서비스로 등록한다. node.js 경로, jupyterlab 을 위한 시작 환경이 필요하다.

systemd의 unit 위치는 OS 마다 조금 다른 것 같다.

여기서는 /etc/systemd/system 밑에 jupyter.service 라는 유닛 파일에 아래 같이 파이썬 환경을 포함해 작성한다.

가상환경을 사용하고 있으므로 systemd unit의 ExecStart 의 python도 가상환경 위치로 지정해 주어야 한다.

유닛 파일: /etc/systemd/system/jupyter.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=My Jupyter-Notebook

[Service]
Type=simple
PIDFile=/run/jupyter-notebook.pid
# nodejs path
Environment="PATH=/home/qkboo/.nvm/versions/node/v12.18.0/bin/:/usr/local/bin:/ usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin"

# anaconda: tf2
ExecStart=/home/qkboo/anaconda3/envs/tf2/bin/jupyter-lab --config /home/qkboo/Home/mybook_config.py
User=qkboo
Group=qkboo
WorkingDirectory=/home/qkboo/Home/Jupyter-Notebook/
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

유닛 파일 등록과 시작

jupyter.service 파일을 등록한다.

1
$ sudo systemctl enable jupyter

등록한 유닛 파일을 확인해 보자.

1
2
3
$ sudo systemctl list-unit-files | grep jupyter
jupyter_book.service disabled enabled
jupyter.service enabled enabled

그리고 데몬을 리로드 한다.

1
2
$ sudo systemctl daemon-reload
$ sudo systemctl start jupyter

실행한 서비스를 종료하려면

1
$ sudo systemctl stop jupyter

실행 상태를 확인한다.

1
$ sudo systemctl status jupyter

유닛 파일 등록 해지

1
2
$ sudo systemctl disable jupyter
Removed /etc/systemd/system/multi-user.target.wants/jupyter.service.

서비스 상태

해당 서비스 상태 확인

1
$ sudo systemctl status jupyter

구동에 실패한 서비스 보기

1
$ sudo systemctl list-units --state=failed

enabled 상태인 서비스 목록

1
$ sudo systemctl list-units --state=enabled

[OpenCV] virtualenv 이용 설치

OpenCV 설치

OpenCV 를 파이썬 기본 패키지 관리자 pip 와 venv 가상환경을 이용해서 윈도우즈, 맥 및 리눅스에서 OpenCV 를 설치하는 과정을 살펴보겠다.

    1. 윈도우즈에서
    1. macOS에서
    1. Linux에서

1) 윈도우즈 pip 기반 OpenCV 설치

윈도우 기반에서 OpenCV 를 사용하기 위해서 pip 기반으로 설치를 해보자.

whl 파일로 설치

윈도우에서 opencv를 빌드된 버전을 설치하기 위해서 https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv 에 있는 .whl 파일을 다운로드 받느다.

1
> pip install c:\downloads\opencv_python‑3.3.1‑cp36‑cp36m‑win_amd64.whl

pip

OpenCV의 main module만 사용한다면 아래처럼 설치하면 됩니다.

1
> pip install opencv-python

만약 main module과 extra module을 같이 사용하고 싶다면 아래처럼 설치합니다.

1
> pip install opencv-contrib-python

2) virtualenv 가상환경에서 openCV 설치

Python 가상환경과 Opencv

파이썬 개발시 virtualenv 를 사용한다면 OpenCV 라이브러리를 연결해 줄 필요가 있다. virtualenv 가상환경 생성시 파이썬 라이브러리는 복사가 안된다 그래서 가상환경 생성후에 cv2.so 라이브러리를 링크해줄 필요가 있다.

가상환경에 cv2.so 연결하기

python2 가상환경 cv3python2 가 있고, 여기에 OpenCV 를 사용하려면 다음 같이 cv2.so 라이브러리를 링크해 준다.

1
2
$ cd ~/.virtualenvs/cv3python2/lib/python2.7/site-packages/
$ ln -s /usr/local/lib/python2.7/dist-packages/cv2.so cv2.so

역시 python3 가상환경 cv3python3 가 있다면 python3 라이브러리에 있는 cv2.so 라이브러리를 링크해 준다.

1
2
$ cd ~/.virtualenvs/cv3python3/lib/python3.4/site-packages/
$ ln -s /usr/local/lib/python3.4/dist-packages/cv2.cpython-34m.so cv2.so

또한 cv2.so를 사용하기 위해서 각 가상환경에 numpy를 설치해 준다. Raspberry Pi 2에서 numpy를 pip로 설치할 때 약 10분 이상 소요된다.

1
2
3
4
5
$ workon cv3python2
(cv3python2) :~/ $ pip install numpy

$ workon cv3python3
(cv3python3) :~/ $ pip install numpy

마직막으로 파이썬을 실행하고 cv2를 테스트한다.

1
2
3
4
5
6
7
8
(cv3python3) ~/$ python
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0'
>>>

OpenCV 테스트

https://cinema4dr12.tistory.com/1283

파이썬을 실행해 cv2 라이브러리를 사용해 보자.

1
2
3
4
5
6
7
8
$ python
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0'
>>>

시스템에서 파이썬이 두 개 이상 설치되어 있으면 일반적을 Python2.7 버전이 기본 파아썬 이다.

1
2
3
4
5
6
7
8
$ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0-dev'
>>>

참조

[OpenCV] anaconda 이용 설치

OpenCV 설치

OpenCV 를 설치하기 위해서 소스 빌드, 패키지 설치 방법이 있다. 여기서 pip 기반 가상환경 그리고 Anaconda 를 사용한다는 가정에서 윈도우즈, 맥에서 OpenCV 를 설치하는 과정을 살펴보겠다.

    1. 윈도우즈에서
    1. macOS에서
    1. Linux에서

1) 윈도우즈에서 OpenCV 설치

윈도우 기반에서 OpenCV 를 사용하기 위해서 Anaconda 배포본을 사용하는 것이 가장 쉽다.

whl 파일로 설치

윈도우에서 opencv를 빌드된 버전을 설치하기 위해서 https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv 에 있는 .whl 파일을 다운로드 받느다.

1
> pip install c:\downloads\opencv_python‑3.3.1‑cp36‑cp36m‑win_amd64.whl

pip

OpenCV의 main module만 사용한다면 아래처럼 설치하면 됩니다.

1
> pip install opencv-python

만약 main module과 extra module을 같이 사용하고 싶다면 아래처럼 설치합니다.

1
> pip install opencv-contrib-python

conda 명령으로 설치하기

Anaconda 3가 설치되어 있다면 명령어 한 줄 입력만으로도 거의 최신 버전(글 작성시 버전 3.6.0)의 Python-OpenCV 라이브러리를 설치할 수 있다:

1
> conda install -c conda-forge opencv

conda-forge에 등록되어 있는 OpenCV 라이브러리에 대한 상세한 설명은 링크를 통해 확인할 수 있습니다. 필요한 경우, python virtualenv를 생성하여 개발환경 패키지를 관리할 수 있다.

OpenCV 3.3의 가장 큰 변화는 Deep Learning in OpenCV 라고 할 수 있겠습니다. 해당 링크에서 Deep Learning 관련 추가된 사항을 확인할 수 있습니다. 이외에 자세한 변경 로그는 OpenCV Change Logs Version:3.3을 참고하시면 되겠습니다.

여담으로 최신 버전 OpenCV 3.3.1 버전 이후에는 JavaScript Interface가 추가되어 인터랙티브 웹-기반 OpenCV 어플리케이션 구현이 공식적으로 가능해졌다고 한다.


OpenCV 테스트

https://cinema4dr12.tistory.com/1283

파이썬을 실행해 cv2 라이브러리를 사용해 보자.

1
2
3
4
5
6
7
8
$ python
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0'
>>>

시스템에서 파이썬이 두 개 이상 설치되어 있으면 일반적을 Python2.7 버전이 기본 파아썬 이다.

1
2
3
4
5
6
7
8
$ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0-dev'
>>>

Python 가상환경과 Opencv

파이썬 개발시 virtualenv 를 사용한다면 OpenCV 라이브러리를 연결해 줄 필요가 있다. virtualenv 가상환경 생성시 파이썬 라이브러리는 복사가 안된다 그래서 가상환경 생성후에 cv2.so 라이브러리를 링크해줄 필요가 있다.

가상환경에 cv2.so 연결하기

python2 가상환경 cv3python2 가 있고, 여기에 OpenCV 를 사용하려면 다음 같이 cv2.so 라이브러리를 링크해 준다.

1
2
$ cd ~/.virtualenvs/cv3python2/lib/python2.7/site-packages/
$ ln -s /usr/local/lib/python2.7/dist-packages/cv2.so cv2.so

역시 python3 가상환경 cv3python3 가 있다면 python3 라이브러리에 있는 cv2.so 라이브러리를 링크해 준다.

1
2
$ cd ~/.virtualenvs/cv3python3/lib/python3.4/site-packages/
$ ln -s /usr/local/lib/python3.4/dist-packages/cv2.cpython-34m.so cv2.so

또한 cv2.so를 사용하기 위해서 각 가상환경에 numpy를 설치해 준다. Raspberry Pi 2에서 numpy를 pip로 설치할 때 약 10분 이상 소요된다.

1
2
3
4
5
$ workon cv3python2
(cv3python2) :~/ $ pip install numpy

$ workon cv3python3
(cv3python3) :~/ $ pip install numpy

마직막으로 파이썬을 실행하고 cv2를 테스트한다.

1
2
3
4
5
6
7
8
(cv3python3) ~/$ python
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.1.0'
>>>

Gstreamer

1
$ sudo apt install python3-gst-1.0

참조

[OpenCV] Source build

OpenCV를 사용하는데 여러 방법이 있겠지만 SBC 컴퓨터들에서 소스로 빌드해서 사용해야할 경우가 있다.

OpenCV 소스 빌드

여기서 OpenCV를 개발 도구와 라이브러리들과 함게 소스를 빌드해서 사용하는 방법을 살펴보겠습니다.

  • Raspberry Pi 3: Raspbian Jessie
  • Odroid C2: Armbian
  • ROCK64: Armbian

빌드는 OpenCV 3.1.1 버전을 대상으로 수행했다.

OpenCV3.1 빌드로 설치

http://docs.opencv.org/3.1.0/df/d65/tutorial_table_of_content_introduction.html

OpenCV 3.1를 빌드하는데 필요한 패키지

  • GCC 4.4.x or later
  • CMake 2.8.7 or higher
  • Git
  • GTK+2.x or higher, including headers (libgtk2.0-dev)
  • pkg-config
  • Python 2.6 or later and Numpy 1.5 or later with developer packages ( python-dev, python-numpy)
  • ffmpeg or libav development packages: libavcodec-dev, libavformat-dev, libswscale-dev
  • [optional] libtbb2 libtbb-dev
  • [optional] libdc1394 2.x
  • [optional] libjpeg-dev, libpng-dev, libtiff-dev, libjasper-dev, libdc1394-22-dev

그리고 VideoStreaming이 필요하면 gstramer 필요.

패키지 설치

기존 패키지로 설치되 opencv가 있으면 제거한다.

1
2
$ sudo apt remove libopencv
$ sudo apt remove opencv

최신 소프트웨어 상태로 업데이트 합니다.

1
2
$ sudo apt update
$ sudo apt upgrade

먼저 컴파일러와 빌드 관련 패키지를 설치합니다.

1
2
$ sudo apt install build-essential
$ sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev

GTK 개발용 라이브러리는 GUI를 구성할 때 필요하다.

1
$ sudo apt install libgtk-3-dev

이미지 처리에 필요한 패키지를 설치한다.

1
$ sudo apt install libgphoto2-dev libjpeg-dev  libtiff-dev libtiff5-dev libjasper-dev libpng12-dev libpng-dev
  • libtbb2 libtbb-dev

필요하다면 비디오 입출력 관련한 패키지를 설치해야 한다. OpenCV에서 비디오 파일을 읽는데 필요하다.

1
$ sudo apt install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev

libdc1394-22-dev

필요하면 스트리밍 처리에 필요한 gstreamer를 설치한다.

1
$ sudo apt install gstreamer-1.0

OpenCV 안에서 다양한 최적화 작업에 필요한 다음 패키지를 설치한다.

1
$ sudo apt install libatlas-base-dev gfortran

마지막으로 파이썬에서 사용한다면 꼭 numpy 를 설치해야 한다. numpy 는 pip로 설치해야 한다.

  • OpenCV Python에서 이미지를 NumPy의 다차원배열로 표현해 사용하고 있다:

시스템에 Python2.7과 python3.4가 설치되어 있다면, 각 pip버전을 명시해서 각각 설치해야 하는 듯 하다. numpy가 제대로 인식이 안되면 Opencv용 python 모듈이 빌드가 안된다.

Raspbian jessie 2016-09-23 버전 이후에는 numpy가 기본으로 설치되어 있다.

1
2
~$ sudo pip2 install numpy
~$ sudo pip3 install numpy
  • Raspberry Pi 2에서 numpy를 pip로 설치할 때 약 10분 이상 소요된다.

혹은 업그레이드 해준다.

1
2
$ sudo pip2 install --upgrade numpy
$ sudo pip3 install --upgrade numpy

numpy 설치후 다음 같이 제대로 동작하는지 확인해 보자

1
2
3
4
5
6
7
8
9
10
11
$:~ $ python2
...

$:~ $ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.__version__
'1.10.4'
>>>

파이썬에서 사용하려면 다음 같이 파이썬 관련 라이브러리가 필요

1
$ sudo apt install python-dev python3-dev python-numpy python3-numpy

개발환경을 apt 방식으로 구성했다면, numpy도 apt로 설치 할 수 있다 – 왠지 잘 안됐다.
$ sudo apt install python-numpy

마지막으로 파이썬에서 matplotlib를 이용한다면 python3-gtk 패키지를 설치해 준다.

1
$sudo apt install python3-gtk

Opencv 다운로드 및 빌드 확경 구성

1
2
3
4
$ cd ~
$ git clone https://github.com/Itseez/opencv.git
$ cd opencv
$ git checkout 3.1.0

빌드를 설정하기 위해서 build폴더를 만든다.

파이썬 환경이 있는 cv 가상환경

build 를 준비

1
2
3
~$ cd opencv
~$ mkdir build
~$ cd build

빌드를 수행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
~$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D BUILD_EXAMPLES=ON ..

...
-- Python 2:
-- Interpreter: /usr/bin/python2.7 (ver 2.7.9)
--
-- Python 3:
-- Interpreter: /usr/bin/python3.4 (ver 3.4.2)
--
-- Python (for build): /usr/bin/python2.7


위 스크립은 OpenCV 3.1.0의 CMake 빌드 버그로, OpenCV 3.0.0 까지 -D INSTALL_C_EXAMPLES=ON으로 빌드했지만 3.1.0에서는 -D INSTALL_C_EXAMPLES=OFF로 해야한다.
또한 opencv_contrib 모듈을 함께 빌드한다면 -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules를 함께 사용한다.

컴파일과 설치

그리고 컴파일 한다.

1
2
3
4
5
6
7
8
~(cv)$ make -j4       # RPi2

...
[100%] Built target example_ocl_tvl1_optical_flow

real 173m22.432s
user 165m58.970s
sys 5m7.060s

싱글로 make시 Raspberry Pi 2 에서 빌드시 약 3시간 소요.
-j 옵션을 이용시 45분 이상 절약.

빌드된 결과중에 python2, python3 관련해서 라이브러리가 제대로 빌드되었는지 라이브러리 폴더를 확인한다.

1
2
$ ls lib/cv2.so
$ ls lib/python3/cv2.cpython-34m.so

이 두 라이브러리가 생성되 있으면 빌드가 제대로 된 것이다.

이제 로컬 시스템에 설치를 한다. 보통 Python2.7과 Python3.4가 함께 설치되 상태일 수 있는데 이 경우 시스템에 기본 Python2.7 환경을 기반으로 설치가 된다.

1
2
3
4
5
6
7
8
9
10
(cv)$ sudo make install
...
-- Installing: /usr/local/include/opencv2/contrib/detection_based_tracker.hpp
-- Installing: /usr/local/lib/python2.7/dist-packages/cv2.so
-- Set runtime path of "/usr/local/lib/python2.7/dist-packages/cv2.so" to "/usr/local/lib"
-- Installing: /usr/local/lib/python2.7/dist-packages/cv.py
-- Installing: /usr/local/lib/libopencv_stitching.so.2.4.11
...

(cv)$ sudo ldconfig

설치된 opencv 패키지 버전을 확인한다.

1
2
$ pkg-config --modversion opencv
3.1.0

cv2.so

Python2.7이 함께 설치되어 있는 경우 빌드시 Python3.x의 site-packages에 파일 cv2.cpython-34mu.so 로 설치되어 있다. 이 파일은 실제 파이썬 바인딩으로 실제 파이썬 환경에서 이 라이브러리가 필요하기 하다. Python3 가상환경에서 이 파일 심볼릭 링크를 cv 환경에 cv2.so라는 이름으로 연결해 준다.

파이썬은 관행적으로 opencv 라이브러리를 cv2.so 파일로 표현하고 있다. python3의 경우 라이브러리 이름을 cv2로 링크해 준다.

1
2
3
4
$ cd /usr/local/lib/python3.4/dist-packages
$ ls
cv2.cpython-34m.so numpy numpy-1.11.2.egg-info
$ sudo ln -s cv2.cpython-34m.so cv2.so