web-dev-qa-db-fra.com

Puis-je utiliser des outils standard pour obtenir le nom complet d'un processus, lorsque son nom comporte des espaces incorporés?

Je comprends qu’il peut être rare qu’un exécutable comporte des espaces, mais cela peut arriver.

Un exemple peut être la meilleure explication ..

A l'aide d'outils standard, je souhaite déterminer l'emplacement (sur le système de fichiers) de l'exécutable qui possède (?) La fenêtre en cours ...

  1. obtenir l'ID de la fenêtre actuelle ... (xdotool getactivewindow)
  2. utilisez l'ID pour obtenir le PID ... (wmctrl -p -l | sed ... ID ....
  3. utilisez le PID pour obtenir le nom de l'exécutable ... (ps -A ... ici c'est là que j'ai des problèmes!

Avec ps, lorsqu’il ne répertorie que le nom de l’exécutable (-o ucmd), il tronque le nom à 15 caractères, ce qui exclut cette option pour tout nom plus long.
L'élargissement de la colonne (-o ucmd:99) ne fait aucune différence. Si pgrep est important, sa correspondance est limitée à 15 en raison de stat (voir: info pgrep ) ..

Les listages dans les variantes du mode "complet" (par exemple, -A w w) ne sont pas utiles lorsque le nom concerné contient des espaces, car ce nom est séparé de ses arguments par un autre espace ! .. De plus, en mode "complet", si le processus a été lancé par un lien, le nom du lien est affiché plutôt que le nom de l'exécutable.

Y a-t-il un moyen de faire cela (en utilisant des outils standard)? ... ou les espaces sont-ils un arrêt spectacle ici?

6
Peter.O

De toute façon, tous les utilitaires tirent leurs informations de _/proc/$PID_, mais il y a (au moins) trois emplacements dans _/proc/$PID_ qui contiennent le nom de l’exécutable, et ils rapportent des informations différentes.

  • Le nom Name dans _/proc/$PID/status_ (également disponible sous une forme plus difficile à analyser dans _/proc/$PID/stat_). C'est le nom de l'exécutable, mais tronqué à 15 caractères. Puisque le noyau effectue la troncature, aucune option pour ps ne peut aider. C’est ce que montre _ps -o comm_ (ou son synonyme _ps -o ucmd_).
  • Le lien symbolique _/proc/$PID/exename_ pointe vers le fichier exécutable. Vous pouvez obtenir son contenu avec readlink /proc/$PID/exename. Contrairement aux informations signalées par ps, seul l'utilisateur qui exécute le processus est autorisé à lire la cible du lien.
  • L'argument zéro du processus, choisi par le shell ou un autre programme qui l'a appelé. Par convention, les shells choisissent le nom de l'exécutable tel que vous l'avez tapé (avec ou sans chemin complet). Vous pouvez obtenir tous les arguments de ps avec _ps -o cmd_ (ou son synonyme _ps -o command_), mais les arguments sont séparés par des espaces. Vous ne pouvez donc pas savoir exactement où s'arrête l'argument zéro. Vous pouvez lire les arguments de _/proc/cmdline_, où ils sont séparés par un caractère nul: </proc/$PID/cmdline awk -vRS='\0' '{print; exit;}' extrait l'argument zéro.

Pour être complet, permettez-moi de mentionner que ces noms peuvent changer au cours du processus, bien que la plupart des programmes ne le fassent pas:

  • Le processus peut changer le champ Name de _/proc/$PID/status_ en appelant prctl avec l'argument _PR_SET_NAME_.
  • Le fichier exécutable peut être renommé ou supprimé. Dans des cas simples, Linux garde la trace du nouveau nom (mais les cas Edge peuvent ne pas fonctionner, par exemple si vous établissez un lien physique vers l'exécutable). Si le fichier est supprimé, le noyau ajoute _(deleted)_ à la cible du lien.
  • L'argument zéro du processus est lu à partir de la mémoire du processus (c'est _argv[0]_ en C). Le processus peut le modifier librement.
7
Gilles
ps $PID | tail -1 | awk '{i=5; while (i<NF) {printf "%s ", $i; i++}; print $NF}'

Où $ PID est le PID que vous avez. La commande complète que vous voulez probablement (basée sur votre question ci-dessus) est:

which "$(ps $(xdotool getwindowpid $(xdotool getactivewindow)) | tail -1 | awk '{i=5; while (i<NF) {printf "%s ", $i; i++}; print $NF}')"
0
zpletan