월별 글 목록: 2026년 2월월

yazi 설치 – tui 탐색기

공식 github: https://github.com/sxyazi/yazi

# 1. 바이너리 설치 (가장 빠름)
curl -sL https://github.com/sxyazi/yazi/releases/latest/download/yazi-x86_64-unknown-linux-gnu.zip -o /tmp/yazi.zip

unzip /tmp/yazi.zip -d /tmp/yazi

cd /tmp/yazi/yazi-x86_64-unknown-linux-gnu

mv yazi ya ~/.local/bin/

# 확인
which yazi
yazi --version

fish함수 생성

# yazi용 fish 함수 생성
mkdir -p ~/.config/fish/functions
cat > ~/.config/fish/functions/y.fish << 'EOF'
function y
    set tmp (mktemp -t "yazi-cwd.XXXXXX")
    yazi $argv --cwd-file="$tmp"
    if set cwd (command cat -- "$tmp"); and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
        builtin cd -- "$cwd"
    end
    rm -f -- "$tmp"
end
EOF

테스트

# fish reload
exec fish

# yazi 실행 (cd on quit 기능 포함)
y

# 또는 직접
yazi

Ubuntu 24.04 Rust 설치

1. 필수 패키지 업데이트

sudo apt update && sudo apt upgrade -y

2. Rust 설치 스크립트 다운로드 & 실행

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 실행 중 1번 선택
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation

3. 환경 변수 로드

source $HOME/.cargo/env #설치 후 shell 마다 다름 확인할 것

4. 설치 확인

rustc --version && cargo --version

5. 추가 빌드도구 설치

sudo apt install build-essential pkg-config libssl-dev -y

Fish + Starship 설치

1단계: 백업 (중요!)

# zsh 설정 백업
cp -r ~/.zsh ~/.zsh_backup.$(date +%Y%m%d) 2>/dev/null || true
cp ~/.zshrc ~/.zshrc_backup.$(date +%Y%m%d) 2>/dev/null || true
cp -r ~/.oh-my-zsh ~/.oh-my-zsh_backup.$(date +%Y%m%d) 2>/dev/null || true
# 현재 셸 확인
echo $SHELL

2단계: fish 설치

# Ubuntu/Debian
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt update
sudo apt install fish

# Fedora
sudo dnf install fish

# Arch
sudo pacman -S fish

3단계: 기본 셸 변경 (선택사항)

# fish를 기본 셸로 등록 (안 하면 zsh 유지하면서 fish만 실행 가능)

which fish
# 출력 예: /opt/homebrew/bin/fish 또는 /usr/bin/fish

# 기본 셸 변경
chsh -s $(which fish)

# 또는 수동으로
sudo chsh -s /opt/homebrew/bin/fish $USER

4단계: Starship 설치

# macOS/Linux
curl -sS https://starship.rs/install.sh | sh

5단계: fish 설정 준비

# 설정 디렉토리 생성
mkdir -p ~/.config/fish/functions
mkdir -p ~/.config/fish/completions

# 기본 설정 파일 생성
touch ~/.config/fish/config.fish

# ip 함수 
touch ~/.config/fish/functions/ip.fish

# starship.toml -> 테마
touch ~/.config/starship.toml

~/.config/fish/config.fish

# ==================================================================
# 1. Environment Variables & Path
# ==================================================================

# Path Configuration (zshrc에서 복사 + ~/.local/bin/env 내용 반영)
set -x PATH $HOME/.local/bin $HOME/.cargo/bin $HOME/.local/share/gem/ruby/3.0.0/bin $PATH

# Load acme.sh env if exists (fish compatible)
if test -f "$HOME/.acme.sh/acme.sh.env"
    # acme.sh.env도 bash 문법일 수 있으므로 주의
    # 간단한 export만 있다면 직접 설정
    set -x ACME_DIRECTORY "https://acme-v02.api.letsencrypt.org/directory"
end

# =================================================================
# 2. Tool Specific Settings
# =================================================================

# fzf optimization (Use fd/fdfind if installed)
if command -v fdfind >/dev/null 2>&1
    set -x FZF_DEFAULT_COMMAND 'fdfind --type f --hidden --follow --exclude .git'
    alias fd="fdfind"
else if command -v fd >/dev/null 2>&1
    set -x FZF_DEFAULT_COMMAND 'fd --type f --hidden --follow --exclude .git'
end

if set -q FZF_DEFAULT_COMMAND
    set -x FZF_CTRL_T_COMMAND $FZF_DEFAULT_COMMAND
end

# fzf fish integration (버전 확인)
if command -v fzf >/dev/null 2>&1
    # 최신 fzf (0.48+)용
    fzf --fish 2>/dev/null | source
    # 또는 이전 버전용
    # source (fzf --fish 2>/dev/null)
end

# ================================================================
# 3. Abbreviations (zsh alias → fish abbr)
# ================================================================

# Safety First (Prevent accidental deletions/overwrites)
abbr -a cp 'cp -i'
abbr -a mv 'mv -i'
abbr -a rm 'rm -i'

# Navigation & Listing (eza)
if command -v eza >/dev/null 2>&1
    abbr -a ls 'eza --icons -F'
    abbr -a ll 'eza -lhg -F --group-directories-first --octal-permissions --time-style long-iso --icons'
    abbr -a l 'eza -lhag -F --group-directories-first --octal-permissions --time-style long-iso --icons'
    abbr -a lt 'eza --tree --icons'
else
    abbr -a ls 'ls -F --color=auto'
    abbr -a ll 'ls -lh --color=auto'
    abbr -a l 'ls -lah --color=auto'
end

# General Utilities
abbr -a cc 'clear'
abbr -a vim 'nvim'
abbr -a vi 'nvim'
abbr -a cat 'batcat'
abbr -a man 'tldr'
abbr -a wt 'curl wttr.in/busan?lang=ko'

# System Maintenance
abbr -a uu 'sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y'

# Docker
abbr -a dps 'docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"'
abbr -a dcps 'docker compose ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"'

# Git (oh-my-zsh 기본 alias들)
abbr -a g 'git'
abbr -a ga 'git add'
abbr -a gaa 'git add --all'
abbr -a gb 'git branch'
abbr -a gba 'git branch -a'
abbr -a gbd 'git branch -d'
abbr -a gc 'git commit -v'
abbr -a gcmsg 'git commit -m'
abbr -a gco 'git checkout'
abbr -a gcp 'git cherry-pick'
abbr -a gd 'git diff'
abbr -a gf 'git fetch'
abbr -a gl 'git pull'
abbr -a glg 'git log --stat'
abbr -a gp 'git push'
abbr -a gpf 'git push --force-with-lease'
abbr -a grb 'git rebase'
abbr -a grba 'git rebase --abort'
abbr -a grbc 'git rebase --continue'
abbr -a grbi 'git rebase -i'
abbr -a grh 'git reset'
abbr -a grhh 'git reset --hard'
abbr -a grm 'git rm'
abbr -a gst 'git status'
abbr -a gsw 'git switch'
abbr -a gswc 'git switch -c'

# =============================================================
# 4. Functions (zsh functions → fish functions)
# =============================================================

# sudo wrapper to use nvim
function sudo
    if test "$argv[1]" = "vi"
        command sudo nvim $argv[2..-1]
    else
        command sudo $argv
    end
end

# zoxide가 있을 때만 abbr 설정
if command -v zoxide >/dev/null 2>&1
    zoxide init fish | source
    
    # cd는 원래대로 두고, z만 스마트 점프
    # (기존 abbr -a cd 'z' 제거하고 아래처럼)
    
    # z로 점프, cd는 정상 cd
    abbr -a z 'z'
    abbr -a zi 'zi'  # 대화형 선택
end

# ===========================================================
# 5. Starship Prompt
# ===========================================================
starship init fish | source

~/.config/starship.toml (Powerlevel10k 스타일)

# =============================================================
# Starship Config - Powerlevel10k Style
# =============================================================

add_newline = true
command_timeout = 1000

# Character (prompt symbol)
[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"
vimcmd_symbol = "[❮](bold green)"

# Directory (truncate like p10k)
[directory]
truncation_length = 3
truncate_to_repo = true
fish_style_pwd_dir_length = 1
format = "[$path]($style)[$read_only]($read_only_style) "
style = "blue bold"

# Git (rich info like p10k)
[git_branch]
symbol = " "
style = "bold purple"

[git_status]
staged = "[+](green)"
modified = "[~](yellow)"
untracked = "[?](red)"
conflicted = "[=](red)"
ahead = "[⇡](green)"
behind = "[⇣](red)"
diverged = "[⇕](red)"
stashed = "[$](cyan)"

# Language versions (only show when relevant)
[nodejs]
format = "via [ $version](bold green) "
detect_files = ["package.json", ".node-version", ".nvmrc"]
detect_extensions = ["js", "mjs", "cjs", "ts", "tsx", "jsx"]

[python]
format = "via [🐍 $version](bold blue) "
detect_files = ["requirements.txt", "pyproject.toml", "setup.py", "Pipfile"]
detect_extensions = ["py"]

[rust]
format = "via [🦀 $version](bold red) "
detect_files = ["Cargo.toml"]

# Go - 모듈 이름을 'golang'으로 변경하거나 최소한으로 설정
[golang]
format = "via [🐹 $version](bold cyan) "
detect_files = ["go.mod"]
detect_extensions = ["go"]

# Cloud/K8s
[aws]
format = '[$profile](bold yellow) '
symbol = "☁️ "

[kubernetes]
format = '[$context](bold blue) '
symbol = "☸️ "
disabled = false

# Execution time (show if > 2s)
[cmd_duration]
min_time = 2_000
format = "[  $duration](yellow)"

# Battery (for laptop)
[battery]
full_symbol = "🔋 "
charging_symbol = "⚡️ "
discharging_symbol = "💀 "
disabled = false

# Time (optional)
[time]
disabled = true
format = "[$time]($style) "
time_format = "%H:%M"

# Jobs (background tasks)
[jobs]
symbol = ""
style = "bold red"

# Hostname (show on SSH)
[hostname]
ssh_only = true
format = "[$hostname](bold yellow) "

~/.config/fish/functions/ip.fish (ip a, ip addr 명령시 ip 부분 색상 강조)

function ip --wraps ip --description 'Enhanced ip command with colors (from zshrc)'
    command ip $argv | awk '
    # Highlight Interface Names (blue bold)
    /^[0-9]+: [^:]+:/ {
        gsub(/^([0-9]+: [^:]+:)/, "\033[1;34m&\033[0m");
        print $0;
        next
    }
    # IPv4 (green bold)
    /inet / {
        gsub(/inet /, "\033[1;32minet \033[0m");
        gsub(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+/, "\033[1;32m&\033[0m");
        print $0;
        next
    }
    # IPv6 (cyan bold)
    /inet6 / {
        gsub(/inet6 /, "\033[1;36minet6 \033[0m");
        gsub(/[0-9a-f:]+\/[0-9]+/, "\033[1;36m&\033[0m");
        print $0;
        next
    }
    { print $0 }'
end

✅ 추가 권장 패키지

# fisher 설치 (선택)
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher

# zsh에서 쓰던 도구들 fish 버전
fisher install jorgebucaran/nvm.fish    # nvm 대체
fisher install patrickf1/fzf.fish       # fzf 통합 강화
fisher install jethrokuan/z             # z 디렉토리 점프 (zoxide 없을 때)

Obsidian 동기화의 완성: Syncthing을 활용한 P2P 구축 가이드

옵시디언(Obsidian)을 여러 기기에서 사용하다 보면 가장 먼저 마주하는 난관이 바로 **’동기화(Sync)’**입니다. 공식 유료 서비스인 Obsidian Sync나 iCloud, Google Drive 같은 클라우드 방식이 존재하지만, 보안과 비용, 그리고 제어권 측면에서 아쉬움을 느끼는 사용자들에게 Syncthing은 가장 완벽한 대안이 될 수 있습니다.

1. 왜 Syncthing인가?

Syncthing은 중앙 서버를 거치지 않고 기기 간에 직접 데이터를 교환하는 오픈소스 P2P 동기화 도구입니다. 이는 데이터가 제3자의 서버에 저장되지 않아 보안성이 뛰어나며, 로컬 네트워크를 활용할 수 있어 속도 또한 매우 빠릅니다.

주요 서비스 비교

비교 항목클라우드 (iCloud/Drive)Obsidian Sync (공식)Syncthing
작동 원리중앙 서버 저장 후 동기화전용 서버 경유기기 간 직접 전송 (P2P)
비용용량에 따른 월 구독료월 $4 ~ $10무료 (Open Source)
데이터 소유권서비스 제공자에게 의존암호화되나 서버에 저장오직 본인 기기에만 저장
네트워크인터넷 연결 필수인터넷 연결 필수로컬 네트워크(Wi-Fi) 활용 가능

2. 동기화 프로세스 및 아키텍처

Syncthing의 핵심은 기기 간의 **’Handshake’**와 **’Delta Update’**입니다. 전체 파일을 매번 전송하는 대신, 변경된 블록(Block) 데이터만 선별적으로 동기화하여 효율성을 극대화합니다.

  1. ID 교환: 각 기기의 고유 ID를 서로 등록하여 신뢰 관계 형성.
  2. 폴더 공유: 동기화할 보관소(Vault) 경로 지정 및 권한 설정.
  3. 실시간 모니터링: 파일 변경 감지 시 즉각적으로 연결된 기기에 전파.

3. 단계별 설정 방법

Step 1. 기기 상호 등록 (Device Pairing)

먼저 동기화할 두 기기(예: PC와 안드로이드 스마트폰)를 연결해야 합니다. 각 기기는 고유한 Device ID를 가지고 있습니다.

  • PC 환경: 웹 GUI를 열고 내 ID 보기를 통해 QR 코드 또는 문자열 ID를 확인합니다.
  • 모바일 환경: Syncthing 앱에서 기기 추가를 선택한 후 PC의 ID를 스캔합니다.
  • 승인: PC 측에서 연결 요청 팝업이 뜨면 승인 버튼을 눌러 페어링을 완료합니다.

Step 2. 보관소(Vault) 폴더 공유

연결된 기기 간에 실제 Obsidian 데이터가 담긴 폴더를 공유하는 단계입니다.

  • 폴더 ID 설정: 두 기기가 동일한 폴더임을 인식할 수 있도록 고유한 폴더 ID를 지정합니다.
  • 경로 지정: 각 기기의 로컬 환경에 맞는 실제 경로를 선택합니다.
  • 전송 모드: 일반적으로 양방향 수정을 위해 송수신(Send & Receive) 모드를 사용합니다.

Step 3. 안정적인 동기화를 위한 최적화 (Android)

안드로이드 환경은 OS의 배터리 최적화 기능이 동기화를 방해할 수 있습니다. 따라서 Syncthing 앱에 대한 배터리 최적화를 해제하고, 필요한 경우 Wi-Fi에서만 작동하도록 설정하여 데이터 소모를 줄일 수 있습니다.

4. 고급 활용 팁 (Technical Tips)

.stignore 파일을 통한 충돌 방지

Obsidian의 설정 파일 중 일부(.obsidian/workspace.json 등)는 기기마다 다른 화면 레이아웃 정보를 담고 있어 충돌을 일으키기 쉽습니다. 보관소 루트에 .stignore 파일을 생성하고 아래 내용을 추가하는 것을 권장합니다.

Plaintext

// .stignore 예시
.obsidian/workspace.json
.obsidian/graph.json

② 데이터 보호를 위한 버전 관리

Syncthing의 ‘파일 버전 관리’ 기능을 활성화하면, 실수로 파일을 삭제하거나 덮어썼을 때 이전 상태로 복구할 수 있는 휴지통 기능을 로컬에 구축할 수 있습니다.

③ 원격 동기화(Relay) 설정

같은 Wi-Fi 환경이 아닌 외부망에서도 동기화가 필요하다면, UPnP를 활성화하거나 **포트 포워딩(22000번)**을 설정하여 릴레이 서버를 거치지 않는 다이렉트 연결 속도를 확보할 수 있습니다.


결론

Syncthing을 이용한 Obsidian 동기화는 초기 설정이 다소 복잡해 보일 수 있으나, 한 번 구축하면 비용, 속도, 개인정보 보호라는 세 마리 토끼를 모두 잡을 수 있는 최상의 솔루션입니다. 나만의 프라이빗한 지식 저장소를 구축하고 싶은 사용자라면 반드시 시도해 보시길 권장합니다.