Come far passare gli arg della riga di comando a un processo in esecuzione su sistemi unix / linux?

StackOverflow https://stackoverflow.com/questions/821837

Domanda

Su SunOS è presente il comando pargs che stampa gli argomenti della riga di comando passati al processo in esecuzione.

Esiste un comando simile su altri ambienti Unix?

È stato utile?

Soluzione

Esistono diverse opzioni:

ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo

Ci sono più informazioni in /proc/<pid> su Linux, basta dare un'occhiata.

Su altri Unix le cose potrebbero essere diverse. Il comando ps funzionerà ovunque, le cose /proc sono specifiche del sistema operativo. Ad esempio su AIX non è presente cmdline in <=>.

Altri suggerimenti

Questo farà il trucco:

xargs -0 < /proc/<pid>/cmdline

Senza gli xarg, non ci saranno spazi tra gli argomenti, perché sono stati convertiti in NUL.

Riga di comando completa

Per Linux & amp; Sistema Unix è possibile utilizzare ps -ef | grep process_name per ottenere l'intera riga di comando.

Sui sistemi SunOS, se si desidera ottenere la riga di comando completa, è possibile utilizzare

/usr/ucb/ps -auxww | grep -i process_name

Per ottenere l'intera riga di comando devi diventare un superutente.

Elenco di argomenti

pargs -a PROCESS_ID

fornirà un elenco dettagliato degli argomenti passati a un processo. Produrrà la matrice di argomenti in questo modo:

argv[o]: first argument
argv[1]: second..
argv[*]: and so on..

Non ho trovato alcun comando simile per Linux, ma vorrei usare il comando seguente per ottenere un output simile:

tr '\0' '\n' < /proc/<pid>/environ

Su Linux

cat /proc/<pid>/cmdline

ottieni la riga di comando del processo (inclusi args) ma con tutti gli spazi bianchi cambiati in caratteri NUL.

Puoi utilizzare pgrep con -f (riga di comando completa) e -l (descrizione lunga):

pgrep -l -f PatternOfProcess

Questo metodo ha una differenza cruciale con qualsiasi altra risposta: funziona su CygWin , quindi puoi usarlo per ottenere l'intera riga di comando di qualsiasi processo in esecuzione su Windows (esegui come elevato se si desidera disporre di dati su qualsiasi processo elevato / admin). Qualsiasi altro metodo per farlo su Windows è più imbarazzante, ad esempio .
Inoltre: nei miei test, il modo pgrep è stato l'unico sistema che ha funzionato per ottenere il percorso completo per script eseguiti all'interno del pitone di CygWin .

Un'altra variante della stampa /proc/PID/cmdline con spazi in Linux è:

cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo

In questo modo cat stampa caratteri NULL come ^@ e poi li sostituisci con uno spazio usando sed; echo stampa una nuova riga.

Anziché utilizzare più comandi per modificare lo stream, basta usare uno - tr traduce un carattere in un altro:

tr '\0' ' ' </proc/<pid>/cmdline

Oltre a tutti i modi sopra indicati per convertire il testo, se usi semplicemente 'stringhe', renderà l'output su righe separate per impostazione predefinita. Con l'ulteriore vantaggio che potrebbe anche impedire la visualizzazione di eventuali caratteri che potrebbero confondere il tuo terminale.

Entrambi vengono visualizzati in un solo comando:

stringhe / proc // cmdline / proc // environment

La vera domanda è ... c'è un modo per vedere la riga di comando reale di un processo in Linux che è stata modificata in modo che la cmdline contenga il testo modificato invece del comando effettivo che è stato eseguito.

Su Solaris

     ps -eo pid,comm

simile può essere usato su sistemi unix like.

Su Linux, con bash, per l'output come argomenti citati in modo da poter modificare il comando ed eseguirlo nuovamente

</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
    bash -c 'printf "%q " "${1}"' /dev/null; echo

Su Solaris, con bash (testato con 3.2.51 (1)-release) e senza userland gnu:

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

Esempio di bash di Linux (incolla nel terminale):

{
## 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
}

Output:

MATCH

Esempio di 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
}

Output:

<*>

Puoi semplicemente usare:

ps -o args= -f -p ProcessPid

prova " ps -n " in un terminale linux. questo mostrerà:

1.Tutti i processi RUNNING, la loro riga di comando e i loro PID

  1. Il programma avvia i processi.

Successivamente saprai quale processo uccidere

Se vuoi ottenere il più lungo possibile (non sei sicuro di quali siano i limiti), simile a pargs , puoi usarlo su Linux & Amp; OSX:

ps -ww -o pid,command [-p <pid> ... ]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top