# 1. 바이너리 설치 (가장 빠름)curl-sLhttps://github.com/sxyazi/yazi/releases/latest/download/yazi-x86_64-unknown-linux-gnu.zip-o/tmp/yazi.zipunzip/tmp/yazi.zip-d/tmp/yazicd/tmp/yazi/yazi-x86_64-unknown-linux-gnumvyaziya~/.local/bin/# 확인whichyaziyazi--version
fish함수 생성
# yazi용 fish 함수 생성mkdir-p~/.config/fish/functionscat>~/.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"endEOF
테스트
# fish reloadexecfish# yazi 실행 (cd on quit 기능 포함)y# 또는 직접yazi
curl--proto'=https'--tlsv1.2-sSfhttps://sh.rustup.rs|sh# 실행 중 1번 선택1) Proceed with installation (default)2) Customize installation3) Cancel installation
# fish를 기본 셸로 등록 (안 하면 zsh 유지하면서 fish만 실행 가능)whichfish# 출력 예: /opt/homebrew/bin/fish 또는 /usr/bin/fish# 기본 셸 변경chsh-s$(which fish)# 또는 수동으로sudochsh-s/opt/homebrew/bin/fish $USER
# 설정 디렉토리 생성mkdir-p~/.config/fish/functionsmkdir-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-xPATH $HOME/.local/bin $HOME/.cargo/bin $HOME/.local/share/gem/ruby/3.0.0/bin $PATH# Load acme.sh env if exists (fish compatible)iftest-f"$HOME/.acme.sh/acme.sh.env"# acme.sh.env도 bash 문법일 수 있으므로 주의# 간단한 export만 있다면 직접 설정set-xACME_DIRECTORY"https://acme-v02.api.letsencrypt.org/directory"end# =================================================================# 2. Tool Specific Settings# =================================================================# fzf optimization (Use fd/fdfind if installed)ifcommand-vfdfind>/dev/null2>&1set-xFZF_DEFAULT_COMMAND'fdfind --type f --hidden --follow --exclude .git'aliasfd="fdfind"elseifcommand-vfd>/dev/null2>&1set-xFZF_DEFAULT_COMMAND'fd --type f --hidden --follow --exclude .git'endifset-qFZF_DEFAULT_COMMANDset-xFZF_CTRL_T_COMMAND $FZF_DEFAULT_COMMANDend# fzf fish integration (버전 확인)ifcommand-vfzf>/dev/null2>&1# 최신 fzf (0.48+)용fzf--fish2>/dev/null|source# 또는 이전 버전용# source (fzf --fish 2>/dev/null)end# ================================================================# 3. Abbreviations (zsh alias → fish abbr)# ================================================================# Safety First (Prevent accidental deletions/overwrites)abbr-acp'cp -i'abbr-amv'mv -i'abbr-arm'rm -i'# Navigation & Listing (eza)ifcommand-veza>/dev/null2>&1abbr-als'eza --icons -F'abbr-all'eza -lhg -F --group-directories-first --octal-permissions --time-style long-iso --icons'abbr-al'eza -lhag -F --group-directories-first --octal-permissions --time-style long-iso --icons'abbr-alt'eza --tree --icons'elseabbr-als'ls -F --color=auto'abbr-all'ls -lh --color=auto'abbr-al'ls -lah --color=auto'end# General Utilitiesabbr-acc'clear'abbr-avim'nvim'abbr-avi'nvim'abbr-acat'batcat'abbr-aman'tldr'abbr-awt'curl wttr.in/busan?lang=ko'# System Maintenanceabbr-auu'sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y'# Dockerabbr-adps'docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"'abbr-adcps'docker compose ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"'# Git (oh-my-zsh 기본 alias들)abbr-ag'git'abbr-aga'git add'abbr-agaa'git add --all'abbr-agb'git branch'abbr-agba'git branch -a'abbr-agbd'git branch -d'abbr-agc'git commit -v'abbr-agcmsg'git commit -m'abbr-agco'git checkout'abbr-agcp'git cherry-pick'abbr-agd'git diff'abbr-agf'git fetch'abbr-agl'git pull'abbr-aglg'git log --stat'abbr-agp'git push'abbr-agpf'git push --force-with-lease'abbr-agrb'git rebase'abbr-agrba'git rebase --abort'abbr-agrbc'git rebase --continue'abbr-agrbi'git rebase -i'abbr-agrh'git reset'abbr-agrhh'git reset --hard'abbr-agrm'git rm'abbr-agst'git status'abbr-agsw'git switch'abbr-agswc'git switch -c'# =============================================================# 4. Functions (zsh functions → fish functions)# =============================================================# sudo wrapper to use nvimfunctionsudo if test "$argv[1]" = "vi" command sudo nvim $argv[2..-1] else command sudo $argv endend# zoxide가 있을 때만 abbr 설정if command -v zoxide >/dev/null 2>&1 zoxide init fish | source # cd는 원래대로 두고, z만 스마트 점프 # (기존abbr-acd'z'는제거하고아래처럼)# z로 점프, cd는 정상 cdabbr-az'z'abbr-azi'zi'# 대화형 선택end# ===========================================================# 5. Starship Prompt# ===========================================================starshipinitfish|source
~/.config/starship.toml (Powerlevel10k 스타일)
# =============================================================# Starship Config - Powerlevel10k Style# =============================================================add_newline =truecommand_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 =3truncate_to_repo =truefish_style_pwd_dir_length =1format ="[$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_000format ="[ $duration](yellow)"# Battery (for laptop)[battery]full_symbol ="🔋 "charging_symbol ="⚡️ "discharging_symbol ="💀 "disabled =false# Time (optional)[time]disabled =trueformat ="[$time]($style) "time_format ="%H:%M"# Jobs (background tasks)[jobs]symbol ="✦ "style ="bold red"# Hostname (show on SSH)[hostname]ssh_only =trueformat ="[$hostname](bold yellow) "
~/.config/fish/functions/ip.fish (ip a, ip addr 명령시 ip 부분 색상 강조)
functionip --wraps ip --description 'Enhanced ip command with colors (fromzshrc)' 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-sLhttps://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish|source&&fisherinstalljorgebucaran/fisher# zsh에서 쓰던 도구들 fish 버전fisherinstalljorgebucaran/nvm.fish# nvm 대체fisherinstallpatrickf1/fzf.fish# fzf 통합 강화fisherinstalljethrokuan/z# z 디렉토리 점프 (zoxide 없을 때)
옵시디언(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) 데이터만 선별적으로 동기화하여 효율성을 극대화합니다.
ID 교환: 각 기기의 고유 ID를 서로 등록하여 신뢰 관계 형성.
폴더 공유: 동기화할 보관소(Vault) 경로 지정 및 권한 설정.
실시간 모니터링: 파일 변경 감지 시 즉각적으로 연결된 기기에 전파.
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 파일을 생성하고 아래 내용을 추가하는 것을 권장합니다.
Syncthing의 ‘파일 버전 관리’ 기능을 활성화하면, 실수로 파일을 삭제하거나 덮어썼을 때 이전 상태로 복구할 수 있는 휴지통 기능을 로컬에 구축할 수 있습니다.
③ 원격 동기화(Relay) 설정
같은 Wi-Fi 환경이 아닌 외부망에서도 동기화가 필요하다면, UPnP를 활성화하거나 **포트 포워딩(22000번)**을 설정하여 릴레이 서버를 거치지 않는 다이렉트 연결 속도를 확보할 수 있습니다.
결론
Syncthing을 이용한 Obsidian 동기화는 초기 설정이 다소 복잡해 보일 수 있으나, 한 번 구축하면 비용, 속도, 개인정보 보호라는 세 마리 토끼를 모두 잡을 수 있는 최상의 솔루션입니다. 나만의 프라이빗한 지식 저장소를 구축하고 싶은 사용자라면 반드시 시도해 보시길 권장합니다.