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 ...
xdotool
getactivewindow)wmctrl
-p -l | sed ... ID ....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?
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.
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
_)./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.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:
Name
de _/proc/$PID/status
_ en appelant prctl
avec l'argument _PR_SET_NAME
_.(deleted)
_ à la cible du lien.argv[0]
_ en C). Le processus peut le modifier librement.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}')"