Créer un lookahead négatif dans une commande pgrep / pkill dans une commande unix compliquée

J’écris un démon qui se connecte à d’autres machines pour confirmer qu’un service est en cours d’exécution et également pour le démarrer, l’arrêter ou le tuer. Pour cette raison, les commandes unix sont un peu longues et obscurcies.

La forme de base des commandes qui se forment est la suivante:

bash -c 'ssh -p 22 [email protected] pgrep -fl "APP.*APP_id=12345"' 

Où APP est le nom de l’exécutable distant et APP_id est un paramètre passé à l’application au démarrage.

L’exécutable s’exécutant du côté distant sera démarré avec quelque chose comme:

 /path/to/APP configs/config.xml -v APP_id=12345 APP_port=2345 APP_priority=7 

Le statut de sortie de cette commande permet de déterminer si le service distant est en cours d’exécution ou a été démarré ou supprimé avec succès.

Le problème que je rencontre est que, lors des tests sur ma machine locale, ssh se connecte à la machine locale pour faciliter les choses, mais pgrep appelé de cette manière identifie également la commande ssh que le serveur exécute pour effectuer la vérification.

Par exemple, pgrep peut renvoyer:

 26308 ./APP configs/config.xml APP_id=128bb8da-9a0b-474b-a0de-528c9edfc0a5 APP_nodeType=all APP_exportPort=6500 APP_clientPriority=11 27915 ssh -p 22 user@localhost pgrep -fl APP.*APP_id=128bb8da-9a0b-474b-a0de-528c9edfc0a5 

L’étape logique suivante consistait donc à modifier le modèle pgrep pour exclure «ssh», mais cela semble impossible car pgrep ne semble pas être compilé avec une version PCRE permettant les recherches, par exemple:

 bash -c -'ssh -p 22 user@localhost preg -fl "\(?!ssh\).*APP.*APP_id=12345" 

Cela va générer une erreur regex, donc pour contourner le problème, j’utilisais grep:

 bash -c 'ssh -p 22 [email protected] pgrep -fl "APP.*APP_id=12345" \\| grep -v ssh' 

Cela fonctionne bien pour interroger avec pgrep même si c’est une solution de contournement. Cependant, la prochaine étape d’utilisation de pkill ne fonctionne pas car grep ne peut être efficace:

 bash -c 'ssh -p 22 [email protected] pkill -f "APP.*APP_id=12345"' 

Ne fonctionne pas correctement car pkill détruit également la connexion ssh, ce qui entraîne un mauvais état de sortie. Donc, je reviens à la modification de mon modèle pgrep / pkill et je n’ai pas beaucoup de chance.

Cet environnement peut être simulé avec quelque chose de simple sur une machine locale qui peut ssh sur lui-même sans mot de passe (dans ce cas, APP serait «regarder»):

 watch echo APP_id=12345 

Voici la question posée simplement: Comment faire correspondre «APP» mais pas «ssh user @ host APP» dans pgrep?

C’est une sorte de solution de contournement, mais fait le travail:

 bash -c 'ssh -p 22 [email protected] pgrep -fl "^[^\s]*APP.*APP_id=12345"' 

… qui ne correspond qu’à des commandes sans espace avant le nom de l’application. Ce n’est pas tout à fait complet, car il est possible que le chemin d’access à l’exécutable contienne un répertoire avec des espaces, mais sans la syntaxe de lookaround, je n’ai pas pensé à un autre moyen pour que cela fonctionne.