Come far passare gli arg della riga di comando a un processo in esecuzione su sistemi unix / linux?
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?
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
- 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> ... ]