Permettez-moi d'être direct : si vous utilisez encore bash comme shell interactif en 2026, vous avez soit une très bonne raison soit aucune raison du tout. Dans 95% des cas c'est la deuxième option.
Bash a été écrit en 1989 par Brian Fox pour remplacer le Bourne shell. Il a 37 ans. C'est plus vieux que certains de vos collègues seniors. Il fait le travail, personne ne dit le contraire, mais "il fait le travail" c'est aussi ce qu'on dit d'une Renault 4 pour aller au supermarché. Vous pouvez. La question c'est pourquoi vous le feriez encore.
Zsh existe depuis 1990. Il est installé par défaut sur macOS depuis Catalina (2019) parce qu'Apple en avait assez de distribuer un shell sous licence GPL v3. La raison est contractuelle, le résultat est excellent.
Ce guide est opinionné. Assumez-le.
Au programme : installer zsh sur Linux, macOS et WSL2, le définir comme shell par défaut, configurer ~/.zshrc, ajouter Oh My Zsh et Powerlevel10k, choisir les plugins qui servent vraiment, et dépanner les erreurs classiques. Comptez vingt minutes pour arriver à une configuration complète et stable.
Bash vs Zsh - l'encart que vous attendiez
Soyons honnêtes sur ce que bash fait bien et ce que zsh fait mieux.
Ce que bash fait bien
- Il est présent sur absolument tous les systèmes Unix, y compris ceux qui ont été installés en 2003 et n'ont pas été touchés depuis
- Les scripts bash sont portables - un script bash tourne partout
- La compatibilité POSIX est irréprochable
- Si vous devez vous connecter à un serveur en urgence à 3h du matin avec un utilisateur système basique, bash sera là
- Oh My Bash existe - c'est un fork assumé d'Oh My Zsh pour bash, avec des plugins git, docker, SSH, des themes, et une structure modulaire. Ce n'est pas rien.
Ce que zsh fait mieux - et la liste est longue
| Fonctionnalité | bash | zsh |
|---|---|---|
| Autocomplétion | bash-completion requis, basique | Native, contextuelle, extensible |
| Correction orthographique | shopt -s cdspell, pour cd uniquement | setopt CORRECT, sur les commandes |
| Globbing qualifié | Non - nécessite find | *(om[1,5]), *(Lk+100), ^pattern |
| Historique partagé | Non natif | setopt SHARE_HISTORY |
| Déduplication historique | HISTCONTROL=ignoredups | HIST_IGNORE_DUPS, HIST_SAVE_NO_DUPS, HIST_FIND_NO_DUPS |
| Plugins | Oh My Bash - existe, écosystème limité | Oh My Zsh - 300+ plugins, écosystème massif |
| Themes | Oh My Bash - quelques themes | Oh My Zsh - des centaines, dont Powerlevel10k |
| cd implicite | shopt -s autocd, depuis bash 4.0 | setopt AUTO_CD |
| Array associatifs | Bash 4+ seulement (2009) | Natifs, et bien plus anciens |
Sur Oh My Bash - soyons justes
Oh My Bash existe, fonctionne, et n'est pas une blague. C'est un fork d'Oh My Zsh pour bash, avec des plugins pour git, docker, SSH, de la complétion, des aliases et une structure modulaire qui évite de tout empiler dans .bashrc. Si vous tenez absolument à rester sur bash, installez-le.
Ce que vous n'aurez pas : l'autocomplétion contextuelle native de zsh, zsh-autosuggestions, zsh-syntax-highlighting, le globbing qualifié, et les 15 ans d'écosystème d'Oh My Zsh derrière vous. L'écosystème d'Oh My Bash est plus petit, moins activement maintenu, avec moins de themes et moins de documentation communautaire. C'est l'équivalent de commander le même plat que votre voisin mais en version allégée parce que le chef était moins inspiré ce jour-là.
C'est un choix valide. C'est juste un choix moins bon.
La vraie distinction
bash est parfait pour les scripts. zsh est parfait pour l'usage interactif. Ce sont deux cas d'usage différents et les confondre est l'erreur classique.
Vos scripts de déploiement, vos crons, vos pipelines CI/CD : continuez à écrire #!/bin/bash. La portabilité et la prévisibilité comptent plus que les fonctionnalités avancées dans un contexte automatisé.
Votre shell interactif au quotidien : zsh. Vous n'avez aucune raison de vous infliger bash en 2026 à moins d'être payé pour ça.
Et si quelqu'un dans votre équipe vous dit "je reste sur bash par principe", demandez-lui s'il conduit aussi une Renault 4 par principe. La réponse sera instructive.
Installer Zsh sur Linux, macOS et WSL2
Zsh est packagé partout. L'installation prend trente secondes, c'est ce qui vient après qui demande de l'attention.
Installer Zsh sur Linux
# Debian / Ubuntu
sudo apt update && sudo apt install zsh
# Fedora / RHEL / Rocky / AlmaLinux
sudo dnf install zsh
# Arch / Manjaro
sudo pacman -S zsh
# openSUSE
sudo zypper install zsh
# Alpine
apk add zsh
Installer Zsh sur macOS
Zsh est le shell par défaut de macOS depuis Catalina. Vous l'avez déjà. La version livrée par Apple date de plusieurs années mais n'accuse qu'une version de retard sur l'amont, zsh publiant peu, ce qui n'a aucune conséquence pour 99% des usages.
zsh --version # la version d'Apple suffit très largement
# Si vous voulez la dernière version quand même
brew install zsh
Installer Zsh sur Windows avec WSL2
Zsh ne tourne pas nativement sur Windows. Il tourne dans WSL2, ce qui revient au même en pratique puisque WSL2 est une vraie distribution Linux.
# Dans votre distribution WSL2 (Ubuntu par défaut)
sudo apt update && sudo apt install zsh
Deux points spécifiques à WSL2 :
chshfonctionne, mais Windows Terminal peut relancer bash malgré tout selon la façon dont le profil est configuré. Vérifiez la ligne de commande du profil dans les paramètres de Windows Terminal.- Les performances sont correctes tant que vous restez dans le système de fichiers Linux (
/home/vous). Travailler dans/mnt/c/rend git et la complétion péniblement lents, et ce n'est pas la faute de zsh.
Vérifier l'installation et définir zsh par défaut
# Vérifier la version installée
zsh --version
# zsh 5.9 (x86_64-pc-linux-gnu)
# Vérifier que zsh figure dans la liste des shells autorisés
cat /etc/shells
# Définir zsh comme shell par défaut
chsh -s $(which zsh)
Déconnectez-vous et reconnectez-vous. chsh ne change pas le shell de la session en cours, il change celui des prochaines connexions. C'est la cause numéro un du "j'ai lancé la commande et il ne se passe rien".
Au premier démarrage, zsh affiche zsh-newuser-install, un assistant de configuration en mode texte. Tapez q pour le passer - Oh My Zsh va tout configurer à votre place dans deux minutes.
Si chsh refuse de faire son travail
Sur les machines gérées par LDAP, Active Directory ou une politique d'entreprise, chsh échoue régulièrement avec PAM: Authentication failure ou chsh: user has an invalid shell. Vous n'avez pas toujours le droit de changer votre propre shell, et personne ne prend la peine de vous le dire.
Le contournement, à placer en fin de ~/.bashrc :
# Basculer sur zsh s'il est installé et si le shell est interactif
if [ -x "$(command -v zsh)" ] && [[ $- == *i* ]]; then
exec zsh
fi
exec remplace le processus bash par zsh au lieu d'en empiler un deuxième. Le test $- == *i* est indispensable : sans lui, vous cassez les sessions non interactives, et scp comme rsync ne survivent pas à un shell qui se met à parler.
Migrer de bash à zsh sans rien casser
Votre ~/.bashrc contient probablement dix ans de sédimentation. La tentation est de le copier tel quel dans ~/.zshrc. Ne le faites pas : vous importeriez aussi les bugs.
Ce qui se transfère sans rien changer :
- Les
exportde variables d'environnement, syntaxe identique - Les
alias, syntaxe identique - Les ajouts au
PATH - Les fonctions simples, compatibles dans l'immense majorité des cas
Ce qui ne se transfère pas :
Dans .bashrc | Équivalent zsh |
|---|---|
PS1="..." | Inutile, Powerlevel10k gère le prompt |
shopt -s autocd | setopt AUTO_CD |
shopt -s histappend | setopt APPEND_HISTORY |
HISTCONTROL=ignoredups | setopt HIST_IGNORE_DUPS |
HISTCONTROL=ignorespace | setopt HIST_IGNORE_SPACE |
source /etc/bash_completion | autoload -Uz compinit && compinit |
${BASH_SOURCE[0]} | ${(%):-%x} |
| Tableaux indexés à partir de 0 | Indexés à partir de 1 en zsh |
La dernière ligne mérite qu'on s'y arrête. En zsh, ${tab[1]} est le premier élément, pas le deuxième. C'est le piège qui casse silencieusement les fonctions copiées depuis bash, et il ne produit aucune erreur - juste un résultat faux, ce qui est nettement pire.
La méthode propre : repartir d'un ~/.zshrc vide, ajouter ce dont vous avez besoin, et garder votre ~/.bashrc intact. Il ne coûte rien et vous y reviendrez peut-être.
Pour ce qui doit vivre dans les deux shells, un fichier tiers évite de maintenir la même chose à deux endroits :
# ~/.shell_common
export EDITOR="vim"
export PATH="$HOME/.local/bin:$PATH"
alias k='kubectl'
# à ajouter dans ~/.zshrc ET dans ~/.bashrc
[ -f ~/.shell_common ] && source ~/.shell_common
Oh My Zsh - le gestionnaire de config que tout le monde installe
Oh My Zsh n'est pas zsh. C'est un framework de configuration de zsh - un ensemble de plugins, de themes et de helpers qui rendent zsh immédiatement utilisable sans passer trois semaines à lire la documentation.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Oui, curl | sh. On vient de passer un guide entier sur curl à vous expliquer pourquoi c'est une mauvaise idée. Mais c'est Oh My Zsh, pas un script de la NSA, et vous avez lu le code avant de lancer, évidemment.
Oh My Zsh crée un ~/.zshrc avec une config de base et installe ses fichiers dans ~/.oh-my-zsh/. Votre ~/.zshrc précédent est sauvegardé si vous en aviez un.
La config ~/.zshrc - poser les bases
# ~/.zshrc
# Oh My Zsh
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="agnoster" # on y reviendra
plugins=(git docker kubectl terraform aws node python pip)
source $ZSH/oh-my-zsh.sh
# Options zsh essentielles
setopt AUTO_CD # taper le nom d'un dossier = cd dedans
setopt CORRECT # corriger les typos de commandes
setopt HIST_IGNORE_DUPS # ne pas dupliquer dans l'historique
setopt HIST_IGNORE_SPACE # ne pas historiser les commandes commençant par un espace
setopt SHARE_HISTORY # partager l'historique entre tous les terminaux
setopt EXTENDED_HISTORY # horodater l'historique
setopt AUTO_PUSHD # cd pousse dans la pile de dossiers
setopt PUSHD_IGNORE_DUPS # pas de doublons dans la pile
setopt EXTENDED_GLOB # globbing avancé, dont la négation ^
# Historique
HISTSIZE=50000
SAVEHIST=50000
HISTFILE=~/.zsh_history
# Variables d'environnement
export EDITOR="vim"
export LANG="fr_FR.UTF-8"
export LC_ALL="fr_FR.UTF-8"
HIST_IGNORE_SPACE - le truc que personne ne connaît
Commande précédée d'un espace : elle s'exécute normalement mais n'apparaît pas dans l'historique. Parfait pour les commandes avec des tokens, des mots de passe ou des arguments sensibles que vous ne voulez pas voir traîner dans ~/.zsh_history.
curl -H "Authorization: Bearer mon_token_secret" https://api.example.com
# (espace avant curl - n'apparaît pas dans l'historique)
Votre RSSI vous remercie. Votre historique git blame également.
AUTO_PUSHD et la navigation
cd /var/log
cd /etc/nginx
cd /opt/app
dirs -v
# 0 /opt/app
# 1 /etc/nginx
# 2 /var/log
cd -2 # retour à /var/log
cd -1 # retour à /etc/nginx
Une subtilité qui mérite d'être connue : cette numérotation au - fonctionne parce qu'Oh My Zsh active setopt PUSHD_MINUS, qui inverse le sens de + et de -. Sur un zsh nu, sans Oh My Zsh, c'est cd +2 qu'il faut taper pour le même résultat. Si vous copiez cette astuce dans une config sans framework et qu'elle vous emmène au mauvais endroit, vous savez maintenant pourquoi.
Vous naviguez dans votre pile de répertoires comme dans l'historique de votre navigateur. Pas besoin de retaper les chemins. Si vous faites encore cd ../../../ en 2026, ce guide est pour vous.
Le theme - Powerlevel10k, point final
Oh My Zsh vient avec plus de 150 themes. La majorité sont des curiosités historiques que personne n'utilise depuis 2015. Le theme que vous voulez s'appelle Powerlevel10k et il n'est pas inclus par défaut.
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
Une précision avant que vous n'y investissiez une heure de config : le README de Powerlevel10k affiche depuis 2024 un avertissement sans ambiguïté - support très limité, aucune nouvelle fonctionnalité prévue, la plupart des bugs ne seront pas corrigés. Le dépôt n'est pas archivé et reçoit encore des commits, et son auteur précise que le projet ne devrait pas casser tout seul, ce qui est plausible pour un theme de prompt. Si vous voulez un projet activement développé, Starship est l'alternative sérieuse. Powerlevel10k reste plus rapide et mieux intégré à zsh. Choisissez en connaissance de cause.
Dans ~/.zshrc :
ZSH_THEME="powerlevel10k/powerlevel10k"
Relancez votre terminal. Powerlevel10k lance un assistant de configuration interactif avec des questions sur vos préférences visuelles. Répondez, il génère une config dans ~/.p10k.zsh. Si vous changez d'avis plus tard :
p10k configure
Ce que Powerlevel10k affiche
- Le répertoire courant avec les dossiers parents tronqués intelligemment
- La branche git courante avec le statut (modifications, commits en avance/retard)
- Le contexte kubectl actuel - le cluster et le namespace en cours
- L'environnement Python/Node/Ruby actif
- Le temps d'exécution de la dernière commande si elle a pris plus de 3 secondes
- Le code de retour de la dernière commande si non-zéro
- L'utilisateur et le host si vous êtes en SSH
Tout ça sans ralentir perceptiblement votre terminal parce que Powerlevel10k est écrit de façon obsessionnelle pour la performance. Son auteur a passé des semaines à optimiser des microsecondes. C'est le genre de projet open source qui redonne foi en l'humanité, ou du moins en sa sous-catégorie qui passe ses soirées à profiler des shells.
Les polices Nerd Fonts
Powerlevel10k utilise des glyphes spéciaux pour les icônes. Sans une Nerd Font, vous voyez des carrés ou des points d'interrogation - exactement comme votre chef quand vous lui expliquez pourquoi le déploiement a raté.
# macOS
brew install --cask font-meslo-lg-nerd-font
# Linux - installation dans le dossier utilisateur
mkdir -p ~/.local/share/fonts && cd ~/.local/share/fonts
curl -fLO "https://github.com/ryanoasis/nerd-fonts/releases/latest/download/Meslo.zip"
unzip Meslo.zip && rm Meslo.zip
fc-cache -fv
# Arch
sudo pacman -S ttf-meslo-nerd
Sur Windows avec WSL2, la police s'installe côté Windows et pas côté WSL : récupérez Meslo.zip depuis les releases de nerd-fonts, décompressez, clic droit sur les .ttf puis "Installer pour tous les utilisateurs".
Configurez ensuite votre terminal pour utiliser MesloLGS NF :
| Terminal | Où |
|---|---|
| iTerm2 | Preferences > Profiles > Text > Font |
| Ghostty | font-family = MesloLGS NF dans la config |
| Alacritty | font.normal.family dans alacritty.toml |
| Windows Terminal | Paramètres > profil > Apparence > Police |
| GNOME Terminal | Préférences > profil > Texte > Police personnalisée |
| VS Code | "terminal.integrated.fontFamily": "MesloLGS NF" |
Si les icônes restent des carrés après le changement de police, fermez complètement le terminal et rouvrez-le. Recharger l'onglet ne suffit pas.
Les plugins - ce qu'il faut, pas ce qu'on peut
Oh My Zsh vient avec 300+ plugins. La tentation d'en activer 50 est réelle et compréhensible. Résistez. Chaque plugin chargé au démarrage ralentit l'ouverture de votre terminal. Et vous n'utiliserez pas 45 de ces 50 plugins. Vous le savez. Je le sais. On fait semblant que non.
Les plugins inclus dans Oh My Zsh à activer sans hésiter
plugins=(
git # aliases git (ga, gc, gp, gl, gst, glog...)
docker # complétion docker
kubectl # complétion kubectl + alias k=kubectl
terraform # complétion terraform
aws # complétion awscli + AWS_PROFILE dans le prompt
sudo # ESC ESC pour ajouter sudo à la commande précédente
copypath # copier le chemin courant dans le presse-papier
dirhistory # ALT+LEFT/RIGHT pour naviguer dans l'historique de répertoires
jsontools # pp_json, is_json, urlencode_json, urldecode_json
web-search # google terme, github terme depuis le terminal
)
sudo - le plugin qui mérite un paragraphe
Vous tapez une commande, vous appuyez sur Entrée, vous réalisez que vous avez oublié sudo. Normalement : flèche du haut, début de ligne, sudo , Entrée. Avec le plugin sudo : flèche du haut, ESC ESC. Le sudo s'ajoute automatiquement. C'est une économie de deux secondes par jour. Sur une carrière de 30 ans, ça fait environ 6 heures. Les 6 heures les moins chères de votre vie professionnelle.
Les trois plugins à installer séparément - les vrais indispensables
Ces trois plugins ne sont pas inclus dans Oh My Zsh et sont pourtant plus utiles que 90% de ceux qui le sont. C'est injuste. C'est comme ça.
zsh-autosuggestions - suggestions basées sur l'historique
git clone https://github.com/zsh-users/zsh-autosuggestions \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
En tapant une commande, zsh affiche en gris la complétion la plus probable basée sur votre historique. Flèche droite pour accepter, Ctrl+F pour accepter mot par mot. C'est la fonctionnalité qui fait dire "attendez c'est quoi ce truc en gris ?" à tous vos collègues qui vous regardent travailler. Profitez-en, c'est rare d'avoir l'air compétent sans avoir rien fait.
zsh-syntax-highlighting - coloration syntaxique en temps réel
git clone https://github.com/zsh-users/zsh-syntax-highlighting \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
Les commandes valides s'affichent en vert, les commandes inconnues en rouge, les options en jaune, les strings en bleu. Vous repérez les typos avant d'appuyer sur Entrée. Le nombre de fois où vous avez lancé dockre ps et attendu une seconde avant de réaliser - ce plugin règle ça définitivement. À activer en dernier dans la liste des plugins - contrainte du plugin lui-même, pas un caprice.
zsh-z - navigation par fréquence
git clone https://github.com/agkozak/zsh-z \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-z
z apprend les répertoires que vous visitez et vous permet d'y revenir avec un fragment de nom. Après quelques jours d'utilisation :
z radar # cd /home/cyril/projets/rudeops/radar
z nginx # cd /etc/nginx
z log # cd /var/log/nginx (ou le dossier de logs le plus visité)
Pas besoin de taper le chemin complet. z trouve le répertoire le plus probable. C'est la fonctionnalité qui rend le retour à un terminal sans z physiquement douloureux, comme rétrograder vers un téléphone à touches après un smartphone.
Dans ~/.zshrc :
plugins=(
git docker kubectl terraform aws sudo copypath dirhistory jsontools
zsh-autosuggestions
zsh-syntax-highlighting # toujours en dernier
)
# zsh-z séparément
source ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-z/zsh-z.plugin.zsh
Une fois tout chargé, print -c $plugins vous les affiche en colonnes. Voici la machine sur laquelle ce guide a été écrit, avec zsh-z basculé dans le tableau plutôt que sourcé à part - les deux fonctionnent :

Les aliases - votre productivité en clair
La fonction ssht plus bas ouvre une session tmux persistante à travers SSH : deux guides qui se combinent particulièrement bien avec celui-ci.
Oh My Zsh charge des centaines d'aliases via ses plugins. Ceux du plugin git notamment sont bien fournis - gst, gp, gl, glog, et une vingtaine d'autres que vous n'utiliserez jamais mais qui sont là. Vos propres aliases sont souvent plus utiles parce qu'ils correspondent à ce que vous faites vraiment.
# ~/.zshrc
# Navigation
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias ~='cd ~'
# Listage - ou avec eza si installé (recommandé)
alias ls='eza --icons'
alias ll='eza -alF --icons --git'
alias lt='eza --tree --level=2 --icons'
# Git
alias gs='git status'
alias gd='git diff'
alias gds='git diff --staged'
alias gundo='git reset HEAD~1 --mixed'
alias gwip='git commit -am "WIP"'
# Docker
alias dps='docker ps'
alias dpsa='docker ps -a'
alias dimg='docker images'
alias dex='docker exec -it'
alias dlogs='docker logs -f'
# Kubernetes
alias k='kubectl'
alias kns='kubectl config set-context --current --namespace'
alias kctx='kubectl config use-context'
alias kgp='kubectl get pods'
alias kgpa='kubectl get pods -A'
alias kdp='kubectl describe pod'
alias klogs='kubectl logs -f'
# Système
alias ports='ss -tlnp'
alias myip='curl -s ifconfig.me'
alias path='echo $PATH | tr ":" "\n"'
alias reload='source ~/.zshrc'
alias zshconfig='$EDITOR ~/.zshrc'
# Sécurité - confirmation sur les commandes destructives
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
Les fonctions - plus puissantes que les aliases
# Créer un dossier et s'y déplacer immédiatement
mkcd() { mkdir -p "$1" && cd "$1" }
# Extraire n'importe quelle archive sans se souvenir de la syntaxe
extract() {
case $1 in
*.tar.gz) tar xzf $1 ;;
*.tar.bz2) tar xjf $1 ;;
*.zip) unzip $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.7z) 7z x $1 ;;
*) echo "Format non supporté: $1" ;;
esac
}
# Chercher dans l'historique - le "1" est indispensable :
# `history` seul ne renvoie que les 16 dernières entrées
hist() { history 1 | grep "$1" }
# Quel process écoute sur ce port
port() { lsof -i :$1 }
# Backup rapide d'un fichier avant de le modifier
bak() { cp "$1" "$1.bak.$(date +%Y%m%d_%H%M%S)" }
# SSH + tmux automatique - voir les guides SSH et tmux
ssht() { ssh -t "$1" "tmux new-session -A -s main" }
# Kubectl exec sur un pod par pattern de nom
kexec() {
kubectl exec -it \
$(kubectl get pods | grep $1 | head -1 | awk '{print $1}') \
-- ${2:-bash}
}
La complétion - ce que zsh fait vraiment mieux
La complétion de zsh est contextuelle. Elle ne complète pas juste les commandes et les fichiers - elle comprend le contexte de ce que vous faites et adapte les suggestions en conséquence.
# Complétion des options avec description
kubectl get <TAB>
# pods - List pods
# services - List services
# deployments - List deployments
# Complétion des valeurs
kubectl get pods -n <TAB>
# default kube-system monitoring production
# Complétion contextuelle des fichiers
tar xzf <TAB>
# (liste uniquement les .tar.gz et .tgz - pas les .jpg)
Configurer la complétion
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*:descriptions' format '%F{yellow}-- %d --%f'
zstyle ':completion:*' group-name ''
zstyle ':completion:*' squeeze-slashes true
Les raccourcis clavier - arrêter d'user la flèche gauche
Zsh reprend par défaut les raccourcis Emacs. Ce sont les mêmes que dans bash, sauf que presque personne ne les apprend, alors qu'ils font gagner plus de temps que la moitié des plugins de ce guide.
| Raccourci | Effet |
|---|---|
Ctrl+A / Ctrl+E | Début / fin de ligne |
Alt+B / Alt+F | Reculer / avancer d'un mot |
Ctrl+W | Supprimer le mot précédent |
Ctrl+U | Supprimer toute la ligne |
Ctrl+K | Supprimer du curseur jusqu'à la fin |
Ctrl+Y | Recoller ce qui vient d'être supprimé |
Ctrl+R | Recherche incrémentale dans l'historique |
Ctrl+L | Effacer l'écran |
Ctrl+Z puis fg | Suspendre puis reprendre la commande |
ESC ESC | Ajouter sudo devant la commande (plugin sudo) |
La flèche du haut qui filtre l'historique
Par défaut, la flèche du haut remonte tout l'historique. Correctement configurée, elle ne remonte que les commandes qui commencent par ce que vous avez déjà tapé :
# ~/.zshrc
autoload -Uz up-line-or-beginning-search down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey "^[[A" up-line-or-beginning-search
bindkey "^[[B" down-line-or-beginning-search
Tapez docker, puis flèche du haut : vous ne parcourez plus que vos commandes docker. Cinq lignes de config pour un gain quotidien.
Le mode vi pour ceux qui vivent dans vim
# ~/.zshrc
bindkey -v
export KEYTIMEOUT=1 # sinon 0,4 s de latence à chaque ESC
ESC passe en mode commande, i revient en insertion, et toute votre mémoire musculaire vim s'applique à la ligne de commande. KEYTIMEOUT n'est pas facultatif : sans lui, chaque appui sur ESC attend 400 ms au cas où vous taperiez une séquence plus longue, et l'expérience devient exaspérante.
Le globbing qualifié - la vraie différence avec bash
C'est ici que zsh creuse vraiment l'écart. Le globbing qualifié permet de filtrer les fichiers directement dans l'expression glob, sans find, sans xargs, sans pipe. Bash ne peut pas faire ça nativement.
# Récursif - bash fait aussi ** avec globstar activé
ls **/*.js # tous les .js dans les sous-dossiers
ls **/*.{js,ts} # tous les .js et .ts
# Par date de modification - bash ne peut pas faire ça
ls *(om[1,5]) # les 5 fichiers les plus récents
ls *(Om[1,3]) # les 3 fichiers les plus anciens
# Par taille - bash ne peut pas faire ça non plus
# (les unités sont arrondies au supérieur : *(Lm-1) ne renverrait
# que les fichiers vides, d'où le passage en kilo-octets)
ls *(Lk+100) # fichiers > 100ko
ls *(Lk-1024) # fichiers < 1Mo
# Négation - exige setopt EXTENDED_GLOB, qu'Oh My Zsh active deja ;
# sans lui, zsh repond "no matches found"
ls ^*.log # tout sauf les .log
ls ^(*.log|*.tmp) # tout sauf .log et .tmp
# Combinaisons - là bash capitule complètement
ls **/*.log(om[1,10]) # les 10 fichiers .log les plus récents récursivement
Ce qui en bash nécessite find -name "*.log" -newer ref -printf "%T@ %p\n" | sort -rn | head -10 | cut -d' ' -f2- devient une ligne en zsh. Pour ce que vous ferez du contenu de ces fichiers une fois trouvés, grep, awk et sed prennent le relais. Personne ne prétend que la syntaxe zsh est plus lisible. Mais elle est là, elle fonctionne, et elle vous évite de googler la syntaxe de find pour la 400ème fois.
La config finale - votre ~/.zshrc complet
# ~/.zshrc - config RudeOps
# Powerlevel10k instant prompt (doit être en premier)
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Oh My Zsh
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10k"
plugins=(
git
docker
kubectl
terraform
aws
sudo
copypath
dirhistory
jsontools
zsh-autosuggestions
zsh-syntax-highlighting # toujours en dernier
)
source $ZSH/oh-my-zsh.sh
source ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-z/zsh-z.plugin.zsh
# Options
setopt AUTO_CD
setopt CORRECT
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE
setopt SHARE_HISTORY
setopt EXTENDED_HISTORY
setopt AUTO_PUSHD
setopt PUSHD_IGNORE_DUPS
setopt EXTENDED_GLOB
# Historique
HISTSIZE=50000
SAVEHIST=50000
HISTFILE=~/.zsh_history
# Variables
export EDITOR="vim"
export LANG="fr_FR.UTF-8"
# Complétion
autoload -Uz compinit && compinit
zstyle ':completion:*' menu select
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' group-name ''
# Aliases navigation
alias ..='cd ..'
alias ...='cd ../..'
alias ~='cd ~'
alias ls='eza --icons'
alias ll='eza -alF --icons --git'
alias lt='eza --tree --level=2 --icons'
# Aliases git
alias gs='git status'
alias gd='git diff'
alias gundo='git reset HEAD~1 --mixed'
alias gwip='git commit -am "WIP"'
# Aliases docker/k8s
alias dps='docker ps'
alias k='kubectl'
alias kns='kubectl config set-context --current --namespace'
alias kgp='kubectl get pods'
alias kgpa='kubectl get pods -A'
alias klogs='kubectl logs -f'
# Aliases système
alias ports='ss -tlnp'
alias myip='curl -s ifconfig.me'
alias reload='source ~/.zshrc'
# Fonctions
mkcd() { mkdir -p "$1" && cd "$1" }
extract() {
case $1 in
*.tar.gz) tar xzf $1 ;;
*.tar.bz2) tar xjf $1 ;;
*.zip) unzip $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*) echo "Format non supporté: $1" ;;
esac
}
ssht() { ssh -t "$1" "tmux new-session -A -s main" }
kexec() {
kubectl exec -it \
$(kubectl get pods | grep $1 | head -1 | awk '{print $1}') \
-- ${2:-bash}
}
# Powerlevel10k
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
Performance - quand Oh My Zsh devient lent
Oh My Zsh peut ralentir l'ouverture du terminal si vous chargez trop de plugins ou si compinit revalide les completions à chaque démarrage. Comme votre pipeline CI après que quelqu'un a ajouté 12 étapes de validation "juste pour être sûr".
# Mesurer le temps d'ouverture
time zsh -i -c exit
# Profiler ligne par ligne - exige `zmodload zsh/zprof`
# en TOUTE PREMIÈRE ligne de ~/.zshrc, sinon "command not found: zprof"
zsh -i -c "zprof" 2>&1 | head -30
Si votre shell met plus d'une seconde à ouvrir, vous avez un problème. Solutions :
# Accélérer compinit - ne vérifier que si les fichiers ont changé
autoload -Uz compinit
if [[ -n ${ZDOTDIR:-$HOME}/.zcompdump(#qN.mh+24) ]]; then
compinit
else
compinit -C
fi
Zinit - si Oh My Zsh est vraiment trop lent
Zinit charge les plugins en parallèle et en différé. Un shell qui mettait 800ms peut descendre sous 200ms :
bash -c "$(curl --fail --show-error --silent --location \
https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"
# ~/.zshrc avec Zinit
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-syntax-highlighting
zinit light agkozak/zsh-z
zinit ice depth=1; zinit light romkatv/powerlevel10k
Si vous n'avez pas ce problème de performance, Oh My Zsh est suffisant. N'optimisez pas ce qui n'est pas cassé - vous avez sûrement des incidents de prod plus urgents.
Dépannage - les erreurs que tout le monde rencontre
| Symptôme | Cause | Solution |
|---|---|---|
chsh réussit mais bash se lance toujours | Le changement ne prend effet qu'à la session suivante | Se déconnecter puis reconnecter, ou vérifier le profil du terminal |
chsh: PAM: Authentication failure | Compte géré par LDAP ou Active Directory | exec zsh en fin de ~/.bashrc |
Des carrés ou des ? dans le prompt | Nerd Font absente ou non sélectionnée | Installer MesloLGS NF et la choisir dans le terminal |
command not found: compdef | Un plugin est chargé avant oh-my-zsh.sh | Placer source $ZSH/oh-my-zsh.sh avant les plugins externes |
| Le terminal met deux secondes à s'ouvrir | Trop de plugins, ou compinit non mis en cache | zmodload zsh/zprof en tête de ~/.zshrc, puis zprof |
zsh compinit: insecure directories | Droits d'écriture trop larges sur les dossiers de complétion | chmod go-w /usr/local/share/zsh /usr/local/share/zsh/site-functions |
zsh-syntax-highlighting ne colore rien | Il n'est pas chargé en dernier | Le placer en fin de liste plugins=() |
| Les couleurs sont fausses en SSH | TERM mal propagé | export TERM=xterm-256color |
| Les accents s'affichent de travers | Locale non définie | export LANG="fr_FR.UTF-8" |
| L'historique disparaît d'un terminal à l'autre | SHARE_HISTORY absent | setopt SHARE_HISTORY |
Récupérer un shell cassé
Si votre ~/.zshrc empêche le shell de s'ouvrir, vous n'êtes pas coincé. Lancez zsh sans aucune config :
zsh -f # zsh sans lire le moindre fichier de configuration
Et si zsh refuse carrément de démarrer, depuis un autre terminal ou une session SSH :
bash # revenir à bash le temps de réparer
mv ~/.zshrc ~/.zshrc.bak
Gardez ~/.zshrc dans un dépôt de dotfiles versionné. Le jour où une ligne ajoutée à 23h casse votre shell, git diff répond en trois secondes à une question qui coûterait sinon une soirée. Si le git diff en question vous semble illisible, le guide Git traite justement de ce qui vient après le commit/push.
Désinstaller Oh My Zsh ou revenir à bash
Ça arrive, et ce n'est pas un drame.
# Désinstaller Oh My Zsh - restaure le .zshrc sauvegardé à l'installation
uninstall_oh_my_zsh
# Redéfinir bash comme shell par défaut
chsh -s $(which bash)
# Tout supprimer, configuration comprise
rm -rf ~/.oh-my-zsh ~/.zshrc ~/.zsh_history ~/.p10k.zsh
uninstall_oh_my_zsh est une fonction fournie par Oh My Zsh lui-même : elle supprime ~/.oh-my-zsh, restaure le ~/.zshrc sauvegardé lors de l'installation et remet bash si nécessaire. Sur macOS, repasser à bash déclenche un message à chaque ouverture de terminal pour vous rappeler que zsh est le shell par défaut. Apple insiste. Apple a raison.
À retenir
| Config | Pour quoi |
|---|---|
setopt HIST_IGNORE_SPACE | Espace devant = pas dans l'historique |
setopt SHARE_HISTORY | Historique partagé entre terminaux |
setopt AUTO_CD | cd implicite |
setopt AUTO_PUSHD | Navigation dans la pile de répertoires |
zsh-autosuggestions | Suggestions depuis l'historique |
zsh-syntax-highlighting | Coloration en temps réel |
zsh-z | Navigation par fréquence |
plugin sudo | ESC ESC pour ajouter sudo |
time zsh -i -c exit | Mesurer le temps de démarrage |
zmodload zsh/zprof + zprof | Profiler ce qui ralentit |
FAQ
Faut-il installer Oh My Zsh pour utiliser zsh ?
Non. Zsh fonctionne parfaitement seul, et un ~/.zshrc d'une trentaine de lignes vous donne déjà l'essentiel : options, historique, complétion, aliases. Oh My Zsh vous fait gagner quelques heures de lecture de documentation et vous ouvre un catalogue de plugins et de themes. C'est un accélérateur, pas une dépendance. Si vous voulez comprendre ce que fait chaque ligne de votre config, commencez sans lui.
Comment installer zsh sur Windows ?
Via WSL2. Zsh est un shell Unix et n'a pas de version Windows native : vous installez une distribution Linux dans WSL2, puis sudo apt install zsh à l'intérieur. Git Bash et Cygwin proposent des environnements approchants mais l'expérience y est nettement moins bonne, notamment pour Powerlevel10k et la complétion.
Zsh est-il plus lent que bash ?
À l'ouverture du terminal, oui, un peu, et surtout à cause d'Oh My Zsh et des plugins - pas de zsh lui-même. Un zsh nu démarre en quelques dizaines de millisecondes. Un Oh My Zsh chargé de quinze plugins peut atteindre une seconde, ce qui se corrige avec zprof et un peu d'élagage. À l'exécution des commandes, la différence est nulle.
Oh My Zsh vs Zinit vs Antigen - lequel choisir ?
Oh My Zsh si vous démarrez - la communauté est massive, les plugins sont nombreux, la doc est partout. Zinit si la performance vous préoccupe sérieusement. Antigen si vous aimez les choses qui ne sont plus activement maintenues. Oh My Zsh pour 90% des cas, ne cherchez pas plus loin.
Est-ce que mes scripts bash cassent si je passe à zsh ?
Non. Le shebang #!/bin/bash dans vos scripts les fait toujours s'exécuter avec bash. Votre shell interactif et votre shell de script sont deux choses différentes. Tout ce qui a #!/bin/bash continue de fonctionner exactement comme avant. C'est la question numéro un et la réponse est toujours non.
Powerlevel10k vs Starship - lequel choisir ?
Powerlevel10k si vous n'utilisez que zsh - plus riche, mieux intégré, plus rapide. Starship si vous jonglez entre plusieurs shells ou systèmes - il est cross-shell (bash, zsh, fish, PowerShell) et surtout activement maintenu, là où Powerlevel10k annonce lui-même un support très limité. Pour un poste zsh qui ne bouge pas, Powerlevel10k fait toujours le travail ; pour une config que vous comptez faire vivre plusieurs années, Starship est le pari plus sûr.
z vs autojump vs zoxide ?
zsh-z est le plus simple à installer avec Oh My Zsh. zoxide est écrit en Rust, plus rapide, et dispose d'une interface interactive avec fzf - zi pour chercher dans vos dossiers visités. autojump est l'original mais plus lent et moins maintenu. Si vous avez fzf installé, zoxide vaut le détour.
Mes collègues utilisent bash. Je vais avoir des problèmes ?
Vos scripts : non. Votre terminal : aucun impact sur eux. La seule friction possible est si vous partagez des dotfiles en équipe - mais si c'est le cas vous avez des problèmes bien plus profonds que le choix du shell. Comme partager des dotfiles en équipe.
Oh My Bash ça vaut le coup si je veux rester sur bash ?
Pour une transition en douceur ou sur un système où zsh n'est pas disponible, oui - c'est toujours mieux qu'un .bashrc nu. Mais si vous avez le choix, installez zsh. Le delta de confort est significatif et vous ne reviendrez pas en arrière.
Pour aller plus loin
- Oh My Zsh - le site officiel et la liste complète des plugins
- Powerlevel10k - la doc complète du theme
- zsh-users - autosuggestions, syntax-highlighting, history-substring-search
- Oh My Bash - pour les irréductibles
- Zinit - si la performance vous préoccupe
man zshall- 50 000 lignes de documentation. La réponse à votre question est dedans. Bonne chance pour la trouver.