Comment obtenir les arguments de ligne de commande passés à un processus en cours d'exécution sur des systèmes Unix / Linux?
Question
Sur SunOS, il existe une pargs
commande imprimant les arguments de ligne de commande transmis au processus en cours d'exécution.
Existe-t-il une commande similaire sur d'autres environnements Unix?
La solution
Il y a plusieurs options:
ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo
Il y a plus d'informations dans /proc/<pid>
sous Linux, il suffit de regarder.
Sur d’autres Unix, les choses pourraient être différentes. La commande ps
fonctionnera partout, le /proc
dépend du système d’exploitation. Par exemple, sous AIX, il n'y a pas cmdline
dans <=>.
Autres conseils
Cela fera l'affaire:
xargs -0 < /proc/<pid>/cmdline
Sans les xargs, il n'y aura pas d'espace entre les arguments, car ils ont été convertis en NUL.
Ligne de commande complète
Pour Linux & amp; Système Unix, vous pouvez utiliser ps -ef | grep process_name
pour obtenir la ligne de commande complète.
Sur les systèmes SunOS, si vous souhaitez obtenir une ligne de commande complète, vous pouvez utiliser
./usr/ucb/ps -auxww | grep -i process_name
Pour obtenir la ligne de commande complète, vous devez devenir super utilisateur.
Liste des arguments
pargs -a PROCESS_ID
donnera une liste détaillée des arguments passés à un processus. Il va sortir le tableau d'arguments dans ceci:
argv[o]: first argument
argv[1]: second..
argv[*]: and so on..
Je n'ai trouvé aucune commande similaire pour Linux, mais j'utiliserais la commande suivante pour obtenir un résultat similaire:
tr '\0' '\n' < /proc/<pid>/environ
Sous Linux
cat /proc/<pid>/cmdline
vous obtenez la ligne de commande du processus (y compris les arguments), mais tous les espaces blancs sont remplacés par des caractères NUL.
Vous pouvez utiliser pgrep
avec -f
(ligne de commande complète) et -l
(description longue):
pgrep -l -f PatternOfProcess
Cette méthode présente une différence cruciale par rapport aux autres réponses: elle fonctionne sur CygWin , afin que vous puissiez utiliser la ligne de commande complète de tout processus exécuté sous Windows (exécutez-la en tant que surélevé si vous souhaitez obtenir des données sur tout processus élevé / administratif). Toute autre méthode permettant de le faire sous Windows est plus délicate, par exemple .
De plus, dans mes tests, la méthode pgrep a été le seul système à avoir fonctionné pour obtenir le chemin complet des scripts exécutés dans le python de CygWin .
Une autre variante d'impression /proc/PID/cmdline
avec des espaces sous Linux est la suivante:
cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo
De cette manière, cat
imprime caractères NULL sous ^@
, puis vous les remplacez. avec un espace en utilisant sed
; echo
imprime une nouvelle ligne.
Plutôt que d'utiliser plusieurs commandes pour éditer le flux, utilisez simplement one - tr traduit un caractère en un autre:
tr '\0' ' ' </proc/<pid>/cmdline
En plus de toutes les méthodes ci-dessus pour convertir le texte, si vous utilisez simplement des "chaînes", la sortie sera affichée sur des lignes séparées par défaut. L’avantage supplémentaire est qu’il peut également empêcher l’apparition de tous les caractères susceptibles de brouiller votre terminal.
Les deux sorties en une seule commande:
chaînes / proc // cmdline / proc // environ
La vraie question est de savoir s'il existe un moyen de voir la vraie ligne de commande d'un processus sous Linux modifié afin que la cmdline contienne le texte modifié à la place de la commande réelle exécutée.
Sous Solaris
ps -eo pid,comm
similaire peut être utilisé sur les systèmes unix.
Sous Linux, avec bash, pour générer des arguments entre guillemets afin de pouvoir modifier la commande et la réexécuter
</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
bash -c 'printf "%q " "${1}"' /dev/null; echo
Sous Solaris, avec bash (testé avec la version 3.2.51 (1)) et sans gnu userland:
IFS=$'\002' tmpargs=( $( pargs "${pid}" \
| /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
| tr '\n' '\002' ) )
for tmparg in "${tmpargs[@]}"; do
printf "%q " "$( echo -e "${tmparg}" )"
done; echo
Exemple Linux bash (coller dans le terminal):
{
## setup intial args
argv=( /bin/bash -c '{ /usr/bin/sleep 10; echo; }' /dev/null 'BEGIN {system("sleep 2")}' "this is" \
"some" "args "$'\n'" that" $'\000' $'\002' "need" "quot"$'\t'"ing" )
## run in background
"${argv[@]}" &
## recover into eval string that assigns it to argv_recovered
eval_me=$(
printf "argv_recovered=( "
</proc/"${!}"/cmdline xargs --no-run-if-empty -0 -n1 \
bash -c 'printf "%q " "${1}"' /dev/null
printf " )\n"
)
## do eval
eval "${eval_me}"
## verify match
if [ "$( declare -p argv )" == "$( declare -p argv_recovered | sed 's/argv_recovered/argv/' )" ];
then
echo MATCH
else
echo NO MATCH
fi
}
Sortie:
MATCH
Exemple Solaris Bash:
{
## setup intial args
argv=( /bin/bash -c '{ /usr/bin/sleep 10; echo; }' /dev/null 'BEGIN {system("sleep 2")}' "this is" \
"some" "args "$'\n'" that" $'\000' $'\002' "need" "quot"$'\t'"ing" )
## run in background
"${argv[@]}" &
pargs "${!}"
ps -fp "${!}"
declare -p tmpargs
eval_me=$(
printf "argv_recovered=( "
IFS=$'\002' tmpargs=( $( pargs "${!}" \
| /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
| tr '\n' '\002' ) )
for tmparg in "${tmpargs[@]}"; do
printf "%q " "$( echo -e "${tmparg}" )"
done; echo
printf " )\n"
)
## do eval
eval "${eval_me}"
## verify match
if [ "$( declare -p argv )" == "$( declare -p argv_recovered | sed 's/argv_recovered/argv/' )" ];
then
echo MATCH
else
echo NO MATCH
fi
}
Sortie:
<*>Vous pouvez simplement utiliser:
ps -o args= -f -p ProcessPid
essayez & "ps -n &"; dans un terminal linux. cela montrera:
1.Tous les processus en cours d'exécution, leur ligne de commande et leurs PID
- Le programme initie les processus.
Ensuite, vous saurez quel processus tuer
Si vous souhaitez obtenir une réponse aussi longue que possible (ne sachant pas quelles sont les limites), similaire à pages , vous pouvez l’utiliser sous Linux & Amp; OSX:
ps -ww -o pid,command [-p <pid> ... ]