Como obter toda a linha de comando de um processo?

43

Como posso obter os argumentos de comando ou toda a linha de comando de um processo em execução usando seu nome de processo?

Por exemplo, este processo:

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

E o que eu quero é /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pidou os argumentos. Eu sei o nome do processo e quero seus argumentos. Estou usando o Busybox no SliTaz.

Michael
fonte
Deseja processar a saída de ps(não recomendado) ou está procurando algum comando alternativo para psfornecer a saída? O que precisa ser feito quando psfornece várias linhas de saída? imprimir tudo / primeiro / último?
Anthon
1
Qual sistema operacional você usa?
Cyrus
Eu editei minha pergunta. Eu sei o nome do processo e quero seus argumentos. Estou usando o SliTaz (linux minimalista) com o Busybox.
Michael
@ Michael Você já tentou argcomo commandpor resposta @John ?
Pandya
Sim, mas como escrevê-lo em uma variável? Penso em dois comandos: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Mas desta maneira não recebo os argumentos em uma variável
Michael

Respostas:

54

Você pode usar o -oswitch para especificar seu formato de saída:

$ ps -eo args

Na página do manual :

Comando com todos os seus argumentos como uma string. Modificações nos argumentos podem ser mostradas. [...]

Você também pode usar a -popção para selecionar um PID específico:

$ ps -p [PID] -o args

pidoftambém pode ser usado para alternar do nome do processo para o PID, permitindo o uso de -pcom um nome:

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

Obviamente, você também pode usar greppara isso (nesse caso, você deve adicionar a -eopção):

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

O GNU ps também permitirá que você remova os cabeçalhos (é claro, isso é desnecessário ao usar grep):

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

Em outros sistemas, você pode canalizar para AWK ou sed:

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

Edit: se você quiser pegar esta linha em uma variável, use $(...)como de costume:

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

ou com grep:

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)
John WH Smith
fonte
@ Michael substitua argspor command(ou cmd).
Pandya
@ Pandand Ambos cmde commandsão aliases para args, isso provavelmente é desnecessário.
John WH Smith
Eu não tenho uma opção -p usando Busybox: Usage: ps [-o COL1, COL2 = HEADER] [T]
Michael
Você pode usar greppara pegar a linha que você está realmente interessado em: ps -eo args | grep dhcpcd | head -n -1. Eu editei minha resposta.
John WH Smith
Oh, isso parece bom: ps -o args | grep <nome do processo> | head -n 1
Michael
12

Tente algo como isto:

(exemplo de saída do busybox no OpenWrt em um dos meus roteadores)

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/cmdlinecontém os argumentos do processo $PIDcomo uma string C-ish, um após o outro. Cada sequência é zero terminada.

As citações apresentam alguns argumentos ou opções como itens de concha. Você precisa olhar mais de perto as linhas que estão sendo mostradas e onde são usados ​​espaços ou outros caracteres com significado especial para o shell. Você precisará citar os caracteres de alguma forma ou o argumento completo ao associar essas linhas a uma linha de comando novamente.

yeti
fonte
1
tr "\0" " " </proc/991/cmdline
Cyrus
@ Cyrus: Você não pode distinguir argumentos contendo espaços de argumentos separados adjacentes. Ao substituir o byte zero por um espaço, você destrói as informações.
yeti
1
Concordo em substituir \0por `` ser ruim, mas acho tr '\0' '\n' < /proc/$foo/cmdlineque é um pouco mais simples que xargs.
Patrick
printffacilita adicionar aspas à saída, inserir um espaço em vez da nova linha e assim por diante. Ao pensar em adicionar mais processamento, o caminho printfé um bom começo.
21414144Página 1 de
12

Método # 1 - Usando ps

Você poderia usar ps -eaf | grep 1234.

Exemplo

$ 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: O Busybox psnão inclui os -eafswitches, como mostrado acima, de um típico psincluído na maioria dos Linux, no entanto, o Busybox psmostra o que parece ser uma saída muito semelhante ao exemplo que forneci. Você pode instalar o Busybox na maioria dos Linux e executá-lo da seguinte maneira:

$ 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

Você também pode examinar o cmdlinearquivo em que cada PID possui /proc/<pid>.

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

Mas observe que está faltando o espaçamento. Isso ocorre porque um caractere NUL está sendo usado neste arquivo para separar os argumentos da linha de comando. Não se preocupe, porém, estes podem ser retirados.

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

Referências

slm
fonte
2

Conhecendo o PID, apenas exec

cat / proc / pid / cmdline

Por exemplo, 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
fonte