obsidian/wiki/dotfiles/fish-shell-intro.md
2026-04-17 12:54:08 +01:00

105 lines
3.3 KiB
Markdown

---
title: "Fish Shell 4.6 — Introduction & Setup"
aliases: [fish-shell, fish-intro, fish-setup]
tags: [fish, shell, terminal, dotfiles, cli]
sources: [raw/Introduction — fish-shell 4.6.0 documentation.md]
created: 2026-04-17
updated: 2026-04-17
---
## What is Fish?
Fish (**f**riendly **i**nteractive **sh**ell) is a shell focused on usability and interactive use. It works out-of-the-box without configuration.
**Headline features:**
- Syntax highlighting, autosuggestions, tab completion with navigable/filterable lists
- No config required — ready immediately after install
- Easy scripting with a clean, learnable syntax
## Starting & Exiting
```fish
fish # start a fish session inside another shell
exit # end the session
```
## Making Fish Your Default Shell
**Option A — terminal emulator setting** (safest): point your terminal (WezTerm, Kitty, iTerm2) to `/usr/local/bin/fish` directly in its config.
**Option B — login shell** (riskier, see warning below):
```bash
command -v fish | sudo tee -a /etc/shells # register fish
chsh -s "$(command -v fish)" # set as login shell
```
> [!warning] Login shell caveat
> Some Linux distros require the login shell to be Bourne-compatible and source `/etc/profile`. Fish is not Bourne-compatible — this can break PATH and other env vars. Prefer the terminal emulator approach on Linux.
## Configuration Files
| File | Purpose |
|------|---------|
| `~/.config/fish/config.fish` | Main config — runs every shell startup |
| `~/.config/fish/conf.d/*.fish` | Auto-sourced before `config.fish` |
Use guards to scope behavior:
```fish
if status --is-interactive
# interactive-only setup (prompt, aliases, etc.)
end
if status --is-login
set -gx PATH $PATH ~/linux/bin
end
```
Prefer `fish_add_path` over manual PATH manipulation — it deduplicates automatically:
```fish
fish_add_path ~/linux/bin
```
## Shebang Line for Fish Scripts
```fish
#!/usr/bin/env fish
echo Hello from fish $version
```
Use `env fish` (not a hardcoded path) so the script works regardless of where fish is installed. The shebang is only needed when executing a script directly — not when running with `fish /path/to/script`.
## Exit Event Handler
```fish
function on_exit --on-event fish_exit
echo fish is now exiting
end
```
## Inspecting Your Config Changes
```fish
fish_delta # shows what you changed from fish's defaults
```
## Key Takeaways
- Fish is **batteries-included**: syntax highlighting, autosuggestions, and completions work with zero config
- **Don't set fish as login shell on Linux** unless you know your distro supports it — use terminal emulator config instead
- Config lives in `~/.config/fish/config.fish`; modular snippets go in `conf.d/`
- Use `fish_add_path` instead of manually editing `$PATH`
- Script shebangs should use `#!/usr/bin/env fish` for portability
- `fish_delta` reveals your customizations vs defaults
## Related
- [[wiki/dotfiles/linux-terminal-ricing|Linux Terminal Ricing]] — Kitty + Fish + Tide full setup guide
- [[wiki/dotfiles/terminal-cheatsheet|Terminal Cheatsheet]] — daily stack reference with fish/zsh
- [[wiki/dotfiles/wezterm-config|WezTerm Config]] — set fish as the default program in WezTerm
## Sources
- `raw/Introduction — fish-shell 4.6.0 documentation.md` (fishshell.com/docs/current/index.html)