Cómo obtener la línea de comandos args pasa a un proceso en ejecución en sistemas unix/linux?
Pregunta
En SunOS hay pargs
comando que imprime los argumentos de línea de comandos se pasa al proceso de ejecución.
Es que no hay ningún comando similar en otros entornos Unix?
Solución
Hay varias opciones:
ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo
Hay más info en /proc/<pid>
en Linux, sólo echar un vistazo.
En otros Unix, las cosas podrían ser diferentes.El ps
comando funcionará en todas partes, la /proc
cosas específicas de cada sistema operativo.Por ejemplo, en AIX no hay cmdline
en /proc
.
Otros consejos
Esto va a hacer el truco:
xargs -0 < /proc/<pid>/cmdline
Sin el xargs, no habrá espacios entre los argumentos, porque se han convertido a NULs.
Completa línea de comandos
Para Linux y Unix Sistema que se puede utilizar ps -ef | grep process_name
para obtener la totalidad de la línea de comandos.
En SunOS sistemas, si usted desea conseguir una completa línea de comandos, puede utilizar
/usr/ucb/ps -auxww | grep -i process_name
Para obtener la totalidad de la línea de comandos que necesita para convertirse en super usuario.
La lista de argumentos
pargs -a PROCESS_ID
le dará una lista detallada de los argumentos que se pasan a un proceso.Es la salida de la matriz de argumentos como este:
argv[o]: first argument
argv[1]: second..
argv[*]: and so on..
No encontré ningún comando similar para Linux, pero me gustaría utilizar el siguiente comando para obtener una salida similar:
tr '\0' '\n' < /proc/<pid>/environ
En Linux
cat /proc/<pid>/cmdline
conseguir que la línea de comandos del proceso (incluyendo args) pero con todos los espacios en blanco modificado para NUL a los personajes.
Puede utilizar pgrep
con -f
(línea de comando completa) y -l
(descripción larga):
pgrep -l -f PatternOfProcess
Este método tiene una diferencia crucial con ninguna de las otras respuestas:funciona en CygWin, así que usted puede utilizar para obtener la línea de comando completa de cualquier proceso que se ejecuta bajo Windows (ejecutar como elevados si desea que los datos acerca de cualquier elevada/admin proceso).Cualquier otro método para hacer esto en Windows es más torpe, por ejemplo.
Además:en mis pruebas, el pgrep forma en que ha sido el único sistema que funcionó para obtener la ruta de acceso completa para los scripts que se ejecutan dentro de CygWin python.
Otra variante de impresión /proc/PID/cmdline
con espacios en Linux es:
cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo
De esta manera cat
imprime Caracteres NULL como ^@
y luego reemplazarlos con un espacio utilizando sed
; echo
imprime un salto de línea.
En lugar de utilizar múltiples comandos para editar la secuencia, sólo tiene que utilizar uno - tr se traduce a un personaje a otro:
tr '\0' ' ' </proc/<pid>/cmdline
Además de todas las anteriores formas de convertir el texto, si simplemente el uso de 'cuerdas', hará que la salida en líneas separadas por defecto.Con el beneficio añadido de que también puede impedir que cualquiera de los caracteres que puede cifrar su terminal desde el que aparecen.
La salida de un comando:
las cadenas de /proc/cmdline /proc//environ
La verdadera pregunta es...hay una manera de ver la verdadera línea de comandos de un proceso en Linux que ha sido alterado de modo que el cmdline contiene la alteración de texto en lugar de la real de comandos que se ejecute.
En Solaris
ps -eo pid,comm
algo similar puede ser utilizado en sistemas unix.
En Linux, con bash, a la salida del citado argumento, así que usted puede editar el comando y volver a ejecutar es
</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
bash -c 'printf "%q " "${1}"' /dev/null; echo
En Solaris, con bash (probado con 3.2.51(1)-release) y sin 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
Linux bash Ejemplo (pegar en la 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
}
Salida:
MATCH
Solaris Bash Ejemplo:
{
## 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
}
Salida:
MATCH
Usted puede simplemente utilizar:
ps -o args= -f -p ProcessPid
tratar de "ps -n" en una terminal de linux.esto mostrará:
1.Todos los procesos en EJECUCIÓN, la línea de comandos y sus PIDs
- El programa intiate los procesos.
Después se sabe que el proceso de matar
Si usted desea conseguir un tiempo como sea posible (no seguro de qué límites hay), similar a la de Solaris' pargs, usted puede utilizar esto en Linux y OSX:
ps -ww -o pid,command [-p <pid> ... ]