Come ottenere l'intera riga di comando da un processo?


44

Come posso ottenere gli argomenti di comando o l'intera riga di comando da un processo in esecuzione usando il nome del processo?

Ad esempio questo 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 quello che voglio è /sbin/udhcpc -b -T 1 -A 12 -i eth0 -p /var/run/udhcpc.eth0.pido gli argomenti. Conosco il nome del processo e voglio i suoi argomenti. Sto usando Busybox su SliTaz.


Vuoi elaborare l'output da ps(non consigliato) o stai cercando qualche comando alternativo psche ti dia l'output? Cosa bisogna fare quando psfornisce più righe di output? stampa tutto / primo / ultimo?
Anthon,

1
Quale sistema operativo usi?
Ciro,

Ho modificato la mia domanda. Conosco il nome del processo e voglio i suoi argomenti. Sto usando SliTaz (Linux minimalista) con Busybox.
Michael,

@Michael Hai provato argcome commandper la risposta @John ?
Pandya,

Sì, ma come scriverlo in una variabile? Penso a due comandi: PID = pidof <process name>ps -o pid, args | grep $ PID | tr -s "" | cut -d "" -f 2 Ma in questo modo non ottengo gli arg in una variabile
Michael,

Risposte:


55

È possibile utilizzare l' -oopzione per specificare il formato di output:

$ ps -eo args

Dalla pagina man :

Comando con tutti i suoi argomenti come stringa. Modifiche agli argomenti possono essere mostrate. [...]

È inoltre possibile utilizzare l' -pinterruttore per selezionare un PID specifico:

$ ps -p [PID] -o args

pidofpuò anche essere usato per passare dal nome del processo al PID, consentendo quindi l'uso di -pcon un nome:

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

Naturalmente, puoi anche utilizzare grepper questo (nel qual caso, devi aggiungere lo -eswitch):

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

GNU ps ti permetterà anche di rimuovere le intestazioni (ovviamente, questo non è necessario quando si utilizza grep):

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

Su altri sistemi, puoi eseguire il pipe su AWK o sed:

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

Modifica: se vuoi catturare questa linea in una variabile, usa $(...)come al solito:

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

oppure, con grep:

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)

@Michael sostituisce argscon command(o cmd).
Pandya,

@Pandya Entrambi cmde commandsono alias args, questo probabilmente non è necessario.
John WH Smith,

Non ho un'opzione -p usando Busybox: Uso: ps [-o COL1, COL2 = HEADER] [-T]
Michael

È possibile utilizzare grepper prendere la linea si sta effettivamente interessato a: ps -eo args | grep dhcpcd | head -n -1. Ho modificato la mia risposta.
John WH Smith,

Oh, questo sembra buono: ps -o args | grep <nome processo> | head -n 1
Michael

12

Prova qualcosa del genere:

(esempio di output da busybox su OpenWrt su uno dei miei router)

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 gli argomenti del processo $PIDcome stringhe C-ish uno dopo l'altro. Ogni stringa ha terminazione zero.

Le citazioni intorno ad alcuni argomenti o opzioni sono elementi della shell. Devi guardare più da vicino le linee mostrate e dove vengono usati spazi o altri caratteri con un significato speciale per la shell. Dovrai citare quel personaggio (i) in qualche modo o l'argomento completo quando unirai di nuovo queste righe a una riga di comando.


1
tr "\0" " " </proc/991/cmdline
Ciro,

@Cyrus: Non puoi quindi distinguere gli arg che contengono spazi da arg separati adiacenti. Sostituendo il byte zero con uno spazio si distruggono le informazioni.

1
Sono d'accordo a sostituire \0con `` essere cattivo, ma penso tr '\0' '\n' < /proc/$foo/cmdlineche sia un po 'più semplice di xargs.
Patrick,

printfsemplifica l'aggiunta di virgolette all'output, l'inserimento di uno spazio anziché la nuova riga e così via. Quando si pensa di aggiungere più elaborazione, la strada da percorrere printfè un buon inizio.

12

Metodo n. 1 - Utilizzo di ps

Puoi usare ps -eaf | grep 1234.

Esempio

$ 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 psnon include gli -eafswitch come mostrato sopra da un tipico psincluso nella maggior parte dei Linux, tuttavia Busybox psmostra quello che sembra un output molto simile all'esempio che ho fornito. Puoi installare Busybox sulla maggior parte dei Linux ed eseguirlo in questo modo:

$ 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

Metodo n. 2 - Utilizzo di / proc

Puoi anche guardare il cmdlinefile in cui si trova ciascun PID /proc/<pid>.

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

Ma nota che manca la spaziatura. Ciò è dovuto al fatto che un carattere NUL viene utilizzato all'interno di questo file per separare gli argomenti della riga di comando. Non preoccuparti, questi possono essere rimossi.

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

Riferimenti


2

Conoscendo il PID, basta eseguire

cat / proc / pid / cmdline

Ad esempio, per 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
#
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.