← retour aux snippets

ln -s: basculer un symlink de façon atomique

Changer le lien symbolique 'current' vers un nouveau dossier de release sans interruption.

bash système #ln#symlink#deploy#fs

objectif

Basculer un symlink vers une nouvelle release de manière atomique (opération instantanée), sûre et réversible, sans fenêtre d’indisponibilité.

code minimal

# bascule atomique (même dossier -> même filesystem)
set -Eeuo pipefail
new="/srv/app/releases/2005-08-15_1200"
tmp="current.new"

ln -sfn "$new" "$tmp"
mv -f "$tmp" current

utilisation

# 1) préparer la nouvelle release
new="/srv/app/releases/2005-08-15_1200"
[ -d "$new" ] || { echo "absent: $new" >&2; exit 1; }

# 2) bascule atomique avec sauvegarde de l'ancienne cible (pour rollback)
set -Eeuo pipefail
old="$(readlink current || true)"
tmp="current.new"

ln -sfn "$new" "$tmp"
mv -f "$tmp" current

# 3) vérifier la cible
readlink current

# 4) rollback si nécessaire
if [ -n "${old:-}" ] && [ -e "$old" ]; then
  ln -sfn "$old" "$tmp"
  mv -f "$tmp" current
fi

variante(s) utile(s)

# Linux (GNU coreutils): utiliser -T pour forcer le renommage de fichier
ln -sfn "$new" current.new && mv -f -T current.new current

# macOS/BSD: sans -T (rename reste atomique si même dossier)
ln -sfn "$new" current.new && mv -f current.new current

# empêcher la bascule si la nouvelle release est incomplète (fichier sentinelle)
[ -f "$new/.ready" ] || { echo "release non prête"; exit 1; }
ln -sfn "$new" current.new && mv -f current.new current

# consigner la bascule (journal simple)
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
printf '%s %s -> %s\n' "$ts" "${old:-none}" "$new" >> deploy.log

# service qui suit le symlink (ex: systemd): recharger sans restart complet
# systemctl reload myapp.service  # si applicable

notes

  • l’opération mv dans le même dossier est un renommage atomique: aucune fenêtre où “current” pointe vers rien.
  • créez le lien temporaire dans le même répertoire que “current” pour garantir l’atomicité (même filesystem).
  • -sfn: crée un symlink, force le remplacement et traite la cible comme un fichier même si c’est un lien vers un dossier.
  • gardez la valeur précédente avec readlink pour un rollback rapide et traçable.