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 $SHELL2단계: 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 fish3단계: 기본 셸 변경 (선택사항)
# fish를 기본 셸로 등록 (안 하면 zsh 유지하면서 fish만 실행 가능)
which fish
# 출력 예: /opt/homebrew/bin/fish 또는 /usr/bin/fish
# 기본 셸 변경
chsh -s $(which fish)
# 또는 수동으로
sudo chsh -s /opt/homebrew/bin/fish $USER4단계: Starship 설치
# macOS/Linux
curl -sS https://starship.rs/install.sh | sh5단계: 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 없을 때)