Vous lancez une compilation longue sur un Mac distant via SSH, refermez votre ordinateur portable, puis découvrez à votre retour que le terminal a disparu. Le plus gênant n’est pas de devoir relancer la commande, mais de ne pas savoir si la tâche a échoué, s’est terminée ou continue de s’exécuter en arrière-plan. La solution fiable ne consiste pas à allonger aveuglément les délais d’expiration, mais à séparer trois couches : SSH donne accès au nœud, tmux conserve le contexte du terminal, tandis que les journaux et le code de sortie attestent du résultat.
Identifier d’abord la couche affectée par la coupure
La déconnexion du bureau à distance ou de SSH signifie uniquement que le canal interactif entre le client et le Mac distant a été interrompu. Elle n’implique pas l’arrêt du nœud physique. En revanche, un processus au premier plan directement rattaché au pseudo-terminal SSH peut recevoir un signal de déconnexion à la fermeture de la session. Un terminal ouvert depuis l’interface graphique ne constitue pas non plus un point de départ adapté aux tâches sans surveillance, car la fermeture de la fenêtre ou la déconnexion du bureau modifie son cycle de vie.
Commencez par valider l’environnement avec une petite tâche de dix minutes au lieu de tester directement une compilation réelle :
mkdir -p "$HOME/jobs/session-check"
cd "$HOME/jobs/session-check"
date -u +"start=%Y-%m-%dT%H:%M:%SZ" > run.log
sleep 600
date -u +"finish=%Y-%m-%dT%H:%M:%SZ" >> run.log
Après avoir lancé la commande, déconnectez-vous volontairement, reconnectez-vous, puis examinez run.log. Ce test de référence permet de vérifier que le nœud continue bien de fonctionner, mais il ne remplace pas la gestion persistante de la session.
Le maintien de connexion SSH détermine « au bout de combien de temps détecter une connexion défaillante ». tmux détermine « si la tâche conserve un terminal récupérable après la coupure ». L’un ne remplace pas l’autre.
Configurer le maintien de connexion SSH et des délais explicites
Dans le fichier ~/.ssh/config du Mac local, créez une configuration dédiée au nœud. Remplacez l’adresse et le nom d’utilisateur par les valeurs réelles indiquées dans la console :
Host minid-node
HostName <node-address>
User <system-user>
ServerAliveInterval 30
ServerAliveCountMax 3
TCPKeepAlive yes
ConnectTimeout 10
ServerAliveInterval 30 indique que le client envoie une sonde au niveau applicatif toutes les trente secondes. Après trois absences de réponse consécutives, SSH ferme la connexion défaillante au lieu de laisser le terminal bloqué indéfiniment. Ce réglage ne rétablit pas automatiquement la connexion et ne garantit pas la survie des processus au premier plan.
Avant de vous connecter, vous pouvez vérifier la configuration effectivement appliquée :
ssh -G minid-node | grep -E 'serveralive|tcpkeepalive|connecttimeout'
ssh minid-node
Si vous changez souvent de réseau, il est déconseillé de porter les délais d’expiration à plusieurs dizaines de minutes. Détecter plus rapidement qu’une connexion est perdue permet au contraire de revenir sans attendre dans tmux pour consulter l’avancement réel.
Confier les tâches longues à tmux
Vérifiez d’abord si tmux est installé. Dans le cas contraire, installez-le avec le gestionnaire de paquets disponible dans l’environnement actuel :
command -v tmux || brew install tmux
tmux new-session -s ios-build
Le nom de la session doit indiquer la fonction de la tâche, par exemple ios-build, integration-test ou asset-export. Évitez de réutiliser indéfiniment un nom vague comme work. Une fois dans la session, créez un répertoire distinct et affichez la sortie à la fois dans le terminal et dans un fichier journal :
job_dir="$HOME/jobs/ios-build-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$job_dir"
cd "$job_dir"
set -o pipefail
caffeinate -i /path/to/run-build.sh 2>&1 | tee build.log
status=${PIPESTATUS[0]}
printf '%s
' "$status" > exit-code.txt
date -u +"%Y-%m-%dT%H:%M:%SZ" > finished-at.txt
Appuyez sur Control-b, puis sur d pour vous détacher de la session sans interrompre la tâche. Après vous être reconnecté au nœud, exécutez :
tmux list-sessions
tmux attach-session -t ios-build
caffeinate -i signale uniquement pendant l’exécution de la commande que la mise en veille pour inactivité doit être évitée. Il doit rester associé à une tâche précise et ne pas fonctionner en permanence par simple commodité. Pour une compilation entièrement réalisée en ligne de commande, il n’est pas nécessaire de maintenir l’écran allumé.
Éviter les exécutions en double
Après une coupure réseau, commencez par exécuter tmux list-sessions et pgrep -fl run-build. Ne relancez la tâche qu’après avoir confirmé que l’ancienne exécution n’existe plus. Sinon, deux compilations risquent d’écrire simultanément dans le même répertoire de données dérivées, le même cache ou le même chemin de sortie, produisant au final des résultats mélangés difficiles à reproduire.
Utiliser les journaux et le code de sortie comme critères de validation
Voir le terminal continuer à défiler après la reconnexion ne constitue pas une validation. Chaque tâche longue doit au minimum conserver son heure de début, son heure de fin, son journal complet et son code de sortie. Seul un code de sortie égal à 0 signifie que le script s’est terminé avec succès conformément au contrat prévu. La présence d’un mot particulier à la fin du journal ne peut pas s’y substituer.
La séquence de vérification suivante permet d’établir rapidement l’état de la tâche :
| Élément à vérifier | Commande | Conclusion |
|---|---|---|
| La session existe-t-elle ? | tmux list-sessions |
Son existence ne signifie pas que la tâche est encore en cours |
| Le processus existe-t-il ? | pgrep -fl run-build |
Confirme l’instance actuellement exécutée |
| Le journal continue-t-il de croître ? | tail -n 30 build.log |
Indique la progression ou un éventuel blocage |
| L’exécution s’est-elle terminée normalement ? | cat exit-code.txt |
0 indique que le script a réussi |
| Heure de fin | cat finished-at.txt |
Permet de vérifier que le résultat appartient à cette exécution |
Le script doit également créer un nouveau répertoire à chaque exécution au lieu d’écraser les journaux précédents. Lorsque du nettoyage est nécessaire, supprimez par date les répertoires dont l’archivage a été confirmé, plutôt que d’effectuer une suppression récursive sur l’ensemble de ~/jobs.
Simuler volontairement une coupure avant la mise en production
Avant l’utilisation réelle, lancez une tâche de test pouvant être répétée sans risque, puis vérifiez successivement une déconnexion SSH, la fermeture du bureau à distance et un changement de réseau local. Après chaque reconnexion, contrôlez la session tmux, le processus cible, la progression du journal et le fichier contenant le code de sortie.
Si la tâche dépend d’une interface graphique, vérifiez séparément qu’elle continue de s’exécuter après la déconnexion du bureau à distance. Les outils en ligne de commande et les applications graphiques n’ont pas le même cycle de vie. Lorsqu’une tâche se termine prématurément, examinez d’abord le code de sortie et le journal du script, puis vérifiez si le terminal a été fermé, et enfin l’espace de stockage et les ressources du processus. N’attribuez pas systématiquement toutes les défaillances au réseau.
Une liste de contrôle exploitable doit comprendre les points suivants :
- la configuration SSH peut être vérifiée avec
ssh -G; - chaque catégorie de tâche longue utilise une session tmux distincte ;
- les répertoires de tâche sont créés avec un horodatage et n’écrasent pas les anciens résultats ;
- la sortie standard et la sortie d’erreur sont enregistrées dans un même journal consultable ;
- le code de sortie et l’heure de fin en UTC sont enregistrés séparément ;
- après une coupure, l’exécution existante est d’abord récupérée sans relancer la tâche ;
- une fois le travail terminé, les sessions inutiles sont fermées et les résultats archivés.
Questions fréquentes
Une tâche s’arrête-t-elle toujours lorsque la connexion SSH est coupée ?
Non. Un processus attaché directement au terminal peut recevoir un signal de déconnexion, tandis qu’une tâche lancée dans tmux continue normalement. Il faut se reconnecter et vérifier la session ainsi que le journal.
Le réglage ServerAliveInterval suffit-il pour protéger une compilation longue ?
Non. Il détecte une connexion devenue inutilisable, mais ne protège pas le processus. Utilisez tmux et enregistrez la sortie, les erreurs et le code de fin dans des fichiers persistants.
MiniD Cloud Mac
Louez un Mac mini physique dédié à la journée, à la semaine ou au mois
Chaque offre repose sur un Mac mini physique dédié, accessible en bureau à distance et en SSH ; les modèles, régions et durées disponibles figurent sur la page de commande.