Sur OpenWrt, uci répond Invalid argument à toutes les commandes dès qu’un fichier de sauvegarde traîne dans /etc/config/ : la cause n’est pas la commande tapée, mais un mwan3.bak-20261004 posé à côté des vrais fichiers de configuration. C’est le premier des trois pièges BusyBox que j’ai rencontrés en administrant en SSH le routeur 4G de la maison, pendant l’enquête sur le health-check mwan3 qui coupait Internet. Les deux autres : un pgrep -f qui tue sa propre session SSH, et l’absence de nohup.
Contexte : firmware constructeur basé sur OpenWrt 21.02-SNAPSHOT (SoC MediaTek MT7981), accès ssh root@192.168.1.1. BusyBox est l’exécutable unique qui fournit les commandes de base (sh, ps, pgrep, ping…) sur les systèmes embarqués, en version allégée.
Piège 1 : uci Invalid argument à cause d’une sauvegarde
Avant de toucher à la configuration mwan3, j’ai fait ce que tout le monde fait : une copie à côté de l’original.
cp /etc/config/mwan3 /etc/config/mwan3.bak-20261004
À partir de là, uci répondait Invalid argument partout, y compris sur des paquets que je n’avais pas touchés. uci ne lit pas seulement le fichier demandé : il tente de lire ce qui se trouve dans /etc/config/, et la sauvegarde, avec son nom en .bak-…, le fait échouer. Le message ne nomme pas le fichier fautif, ce qui oriente vers une erreur de syntaxe dans la commande.
La parade : sauvegarder hors de /etc/config/. J’ai rangé toutes les copies dans un répertoire daté sous /root/ :
mkdir -p /root/cfg-bak-20261004
cp /etc/config/mwan3 /root/cfg-bak-20261004/
Sur OpenWrt,
/etc/config/n’est pas un dossier où l’on range des fichiers : c’est la base de données d’uci, et tout ce qui s’y trouve est lu.
Piège 2 : pourquoi pgrep -f tue sa propre session SSH ?
Le firmware lance un script de surveillance, watchdog.sh. Pour l’arrêter, j’ai envoyé une commande d’une ligne depuis mon PC :
ssh root@192.168.1.1 'kill $(pgrep -f watchdog.sh)'
La session est tombée aussitôt. pgrep -f cherche le motif dans la ligne de commande complète de chaque processus, pas seulement dans son nom. Or la commande passée à ssh '…' est exécutée par un shell distant dont la ligne de commande contient elle-même watchdog.sh. pgrep ne s’exclut que lui-même : il renvoie donc aussi le PID du shell parent, que kill termine. La commande se tue elle-même, et la connexion SSH avec.
La parade classique consiste à écrire un motif qui ne se correspond pas à lui-même, par exemple pgrep -f '[w]atchdog.sh' : l’expression régulière trouve watchdog.sh, mais la chaîne [w]atchdog.sh du shell ne la contient pas. Plus simple encore : lister d’abord avec ps, puis tuer le PID trouvé dans une seconde commande.
Piège 3 : pas de nohup sous BusyBox
Appliquer une modification WiFi demande un wifi reload. Si la session SSH passe elle-même par le WiFi, elle coupe pendant environ 15 s, et la commande lancée au premier plan meurt avec elle. Le réflexe serait nohup wifi reload &, mais BusyBox de ce firmware ne fournit pas nohup.
La version qui fonctionne : un sous-shell en arrière-plan, détaché des entrées-sorties de la session.
(sleep 2; wifi reload >/tmp/wifireload.log 2>&1) </dev/null >/dev/null 2>&1 &
Chaque élément a un rôle :
sleep 2laisse le temps à la commande SSH de rendre la main avant la coupure.- Les redirections
</dev/null >/dev/null 2>&1détachent le sous-shell du terminal :sshn’attend pas qu’il ferme sa sortie pour terminer la session. >/tmp/wifireload.loggarde une trace consultable une fois reconnecté.
⚠️ Autre écart avec le ping de GNU/Linux : sous BusyBox, ping -i n’accepte que des entiers. Le ping -i0.5 utilisé pour mesurer la perte se lance donc depuis le PC, pas depuis le routeur.
Lessons learned
- Une sauvegarde dans
/etc/config/fait échoueruciavecInvalid argument. Les copies de configuration se rangent ailleurs, par exemple dans/root/cfg-bak-AAAAMMJJ/. pgrep -fcorrespond aussi au shell qui l’a lancé. Dans une commandessh '…'qui contient le motif,kill $(pgrep -f motif)tue la session elle-même.- BusyBox n’a pas toujours
nohup. Un sous-shell( … ) </dev/null >/dev/null 2>&1 &le remplace pour une commande qui doit survivre à la coupure SSH. - Les outils BusyBox ne sont pas ceux de GNU. Options absentes ou réduites (
nohup,ping -i) : vérifier sur la cible avant d’écrire un script.