¿Cómo obtener la línea de comando completa de un proceso?

44

¿Cómo puedo obtener los argumentos del comando o la línea de comando completa de un proceso en ejecución usando su nombre de proceso?

Por ejemplo este proceso:

# ps
PID   USER     TIME   COMMAND
 1452 root       0:00 /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pid

Y lo que quiero es /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pido los argumentos. Sé el nombre del proceso y quiero sus argumentos. Estoy usando Busybox en SliTaz.

Miguel
fuente
¿Desea procesar el resultado desde ps(no recomendado) o está buscando algún comando alternativo para psobtener el resultado? ¿Qué hay que hacer cuando se psobtienen múltiples líneas de salida? imprimir todo / primero / último?
Anthon
1
¿Qué sistema operativo usas?
Cyrus
Edité mi pregunta. Sé el nombre del proceso y quiero sus argumentos. Estoy usando SliTaz (Linux minimalista) con Busybox.
Michael
@Michael ¿Has probado argcomo commandsegún la respuesta de @John ?
Pandya
Sí, pero ¿cómo escribirlo en una variable? Pienso en dos comandos: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Pero de esta manera no obtengo los args en una variable
Michael

Respuestas:

55

Puede usar el -ointerruptor para especificar su formato de salida:

$ ps -eo args

Desde la página del manual :

Comando con todos sus argumentos como una cadena. Se pueden mostrar modificaciones a los argumentos. [...]

También puede usar el -pinterruptor para seleccionar un PID específico:

$ ps -p [PID] -o args

pidoftambién se puede usar para cambiar de nombre de proceso a PID, permitiendo el uso de -pcon un nombre:

$ ps -p $(pidof dhcpcd) -o args

Por supuesto, también puede usar grepesto (en cuyo caso, debe agregar el -einterruptor):

$ ps -eo args | grep dhcpcd | head -n -1

GNU ps también le permitirá eliminar los encabezados (por supuesto, esto es innecesario cuando se usa grep):

$ ps -p $(pidof dhcpcd) -o args --no-headers

En otros sistemas, puede canalizar a AWK o sed:

$ ps -p $(pidof dhcpcd) -o args | awk 'NR > 1'
$ ps -p $(pidof dhcpcd) -o args | sed 1d

Editar: si desea capturar esta línea en una variable, simplemente use $(...)como de costumbre:

$ CMDLINE=$(ps -p $(pidof dhcpcd) -o args --no-headers)

o con grep:

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)
John WH Smith
fuente
@ Michael reemplazar argscon command(o cmd).
Pandya
@Pandya Ambos cmdy commandson alias args, esto probablemente sea innecesario.
John WH Smith
No tengo una opción -p usando Busybox: Uso: ps [-o COL1, COL2 = HEADER] [-T]
Michael
Usted puede usar greppara coger la línea que realmente está interesado en: ps -eo args | grep dhcpcd | head -n -1. Edité mi respuesta.
John WH Smith
Oh, esto se ve bien: ps -o args | grep <nombre del proceso> | head -n 1
Michael
12

Intenta algo como esto:

(ejemplo de salida de busybox en OpenWrt en uno de mis enrutadores)

root@ap8:~# xargs -0 printf '%s\n' </proc/991/cmdline
/usr/sbin/uhttpd
-f
-h
/www
-r
ap8
-x
/cgi-bin
-u
/ubus
-t
60
-T
30
-k
20
-A
1
-n
3
-N
100
-R
-p
0.0.0.0:80
-p
[::]:80

/proc/$PID/cmdlinecontiene los argumentos del proceso $PIDcomo una cadena C-ish una tras otra. Cada cadena tiene terminación cero.

Las citas sobre algunos argumentos u opciones son cosas de shell. Debe mirar más de cerca las líneas que se muestran y dónde se utilizan espacios u otros caracteres con un significado especial para el shell. Deberá citar ese carácter (s) de alguna manera o el argumento completo al volver a unir estas líneas a una línea de comando.


fuente
1
tr "\0" " " </proc/991/cmdline
Cyrus
@Cyrus: No puede distinguir args que contienen espacios de args separados adyacentes en ese momento. Al reemplazar el byte cero con un espacio, destruye la información.
1
Estoy de acuerdo en reemplazar \0con `` ser malo, pero creo tr '\0' '\n' < /proc/$foo/cmdlineque es un poco más simple que xargs.
Patrick
printfhace que sea más fácil agregar comillas a la salida, insertar un espacio en lugar de la nueva línea, etc. Cuando se piensa en agregar más procesamiento, el camino printfes un buen comienzo.
12

Método # 1 - Usando ps

Podrías usar ps -eaf | grep 1234.

Ejemplo

$ ps -eaf | grep 28865
saml     28865  9661  0 03:06 pts/2    00:00:00 bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done
saml     28866 28865  0 03:06 pts/2    00:00:00 sleep 10000

NOTA: Busybox psno incluye los -eafinterruptores como se muestra arriba de un típico psque se incluye con la mayoría de Linux, sin embargo, Busybox psmuestra lo que parece ser una salida muy similar al ejemplo que proporcioné. Puede instalar Busybox en la mayoría de Linux y ejecutarlo así:

$ busybox ps
  852 root       0:00 /sbin/auditd -n
  855 root       0:01 /sbin/audispd
  857 root       0:00 /usr/sbin/sedispatch
  866 root       0:00 /usr/sbin/alsactl -s -n 19 -c -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --initfile=/lib/alsa/init/00main rdaemon
  867 root       0:00 /usr/libexec/bluetooth/bluetoothd
  869 root       0:01 {firewalld} /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
  871 root       0:32 /usr/libexec/accounts-daemon
  873 rtkit      0:05 /usr/libexec/rtkit-daemon
  875 root       0:00 /usr/sbin/ModemManager
  876 avahi      0:03 avahi-daemon: running [dufresne.local]
  878 root       0:54 /usr/sbin/irqbalance --foreground
  884 root       0:00 /usr/sbin/smartd -n -q never
  886 avahi      0:00 avahi-daemon: chroot helper
  891 chrony     0:01 /usr/sbin/chronyd
  892 root       0:01 /usr/lib/systemd/systemd-logind
  893 dbus       1:28 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation

Método # 2 - Usando / proc

También puede mirar el cmdlinearchivo que tiene cada PID /proc/<pid>.

$ cat /proc/28865/cmdline 
bash-csleep 10000; while [ 1 ];do echo hi;sleep 10;done

Pero tenga en cuenta que le falta el espacio. Esto se debe a que se usa un carácter NUL dentro de este archivo para separar los argumentos de la línea de comandos. Sin embargo, no se preocupe, estos pueden eliminarse.

$ tr '\0' ' ' </proc/28865/cmdline
bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done

Referencias

slm
fuente
2

Conociendo el PID, solo ejecutivo

cat / proc / pid / cmdline

Por ejemplo, para PID = 127

# cat /proc/127/cmdline ; echo ""
/usr/lib/jvm/jdk-8-oracle-x64//bin/java-Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager-Djava.library.path=/usr/lib/jni-javaagent:/jmxtrans-agent-1.2.2.jar=/opt/tomcat/conf/jmxtrans-agent.xml-Dcom.sun.management.jmxremote.port=5000-Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false-Djava.endorsed.dirs=/opt/tomcat/endorsed-classpath/opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar-Dcatalina.base=/opt/tomcat-Dcatalina.home=/opt/tomcat-Djava.io.tmpdir=/opt/tomcat/temporg.apache.catalina.startup.Bootstrapstart
#
jmlotero
fuente