web-dev-qa-db-fra.com

Comment obtenir les arguments de ligne de commande passés à un processus en cours d'exécution sur des systèmes unix/linux?

Sur SunOS, la commande pargs imprime 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?

167
Hemant

Il y a plusieurs options:

ps -fp <pid>
cat /proc/<pid>/cmdline

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, les commandes /proc étant spécifiques au système d'exploitation. Par exemple, sur AIX, il n'y a pas de cmdline dans /proc.

264
markus_b

Ça 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.

58
Michael Böckling

Sur Linux

cat /proc/<pid>/cmdline

vous obtenez la ligne de commande du processus (y compris les arguments), mais avec tous les espaces blancs modifiés en caractères NUL.

14
lothar

Pour Linux & Unix System, vous pouvez utiliser ps -ef | grep process_name pour obtenir une ligne de commande complète. 

Sur le système SunOS, si vous souhaitez obtenir une ligne de commande complète, vous pouvez utiliser /usr/ucb/ps -auxww | grep -i process_name. Assurez-vous que dans SunOS pour obtenir la ligne de commande complète, vous devez devenir super utilisateur.

pargs -a PROCESS_ID. Cela donnera une liste détaillée des arguments passés au traitement. Il donnera le tableau des arguments en sortie comme Argv [o]: premier argumen Argv [1]: deuxième .. etc.

Je n'ai trouvé aucune commande similaire, mais je donnerais la commande suivante pour obtenir une sortie semblable à celle-ci tr '\0' '\n' < /proc/<pid>/environ dans un environnement Linux.

14
LOGAN

Vous pouvez utiliser pgrep avec -f (ligne de commande complète) et -l (description longue):

pgrep -l -f PatternOfProcess

Cette méthode a une différence cruciale avec les autres réponses: elle fonctionne sur CygWin, vous pouvez donc l’utiliser pour obtenir la ligne de commande complète de tout processus exécuté sous Windows (exécutez as elevated si vous voulez des données sur n'importe quel processus élevé/admin). 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 qui a fonctionné pour obtenir le chemin complet de scripts s'exécutant dans le python de CygWin.

12

Une autre variante de l'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 comme ^@ et vous les remplacez par un espace à l'aide de sed; echo imprime une nouvelle ligne.

3
Diego

Vous pouvez simplement utiliser:

ps -o args= -f -p ProcessPid
1
Mitar

Sous Linux, avec bash, pour afficher les arguments cités 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 utilisateur:

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

Linux bash Exemple (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:

MATCH
1
Iwan Aucamp

Sur Solaris

     ps -eo pid,comm

similar peut être utilisé sur les systèmes unix. 

1
HuntM

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
1
Tom Evans

En plus de toutes les manières ci-dessus de convertir le texte, si vous utilisez simplement des «chaînes», la sortie sera affichée sur des lignes séparées par défaut. Avec l'avantage supplémentaire, cela peut également empêcher l'apparition de tout caractère susceptible de brouiller votre terminal.

Les deux sorties dans une commande:

chaînes/proc // cmdline/proc // environ

La vraie question est ... existe-t-il un moyen de voir la vraie ligne de commande d'un processus sous Linux qui a été modifiée pour que la cmdline contienne le texte modifié au lieu de la commande réelle qui a été exécutée?.

1
Timothy J. Biggs

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 

  1. Le programme initie les processus. 

Ensuite, vous saurez quel processus tuer

0
repzero

Si vous souhaitez obtenir une configuration aussi longue que possible (similaire à celle de pargs de Solaris (vous ne savez pas quelles sont les limites), vous pouvez l’utiliser sous Linux et OSX:

ps -ww -o pid,command [-p <pid> ... ]
0
pourhaus