2009-10-18 10 views
9

Sto provando a dividere la cmdline di un processo su Linux ma sembra che non posso fare affidamento su di esso per essere separato da caratteri '\ 0'. Sai perché a volte il carattere '\ 0' è usato come separatore e talvolta è uno spazio regolare?Come analizzare/proc/pid/cmdline

Conosci altri metodi per recuperare il nome dell'eseguibile e il percorso? Ho cercato di ottenere queste informazioni con 'ps' ma restituisce sempre la riga di comando completa e il nome dell'eseguibile viene troncato.

Grazie.

risposta

3

Uno scatto al buio, ma è possibile che \0 stia separando i termini e gli spazi separino le parole all'interno di un termine? Ad esempio,

myprog "foo bar" baz 

potrebbe apparire in /proc/pid/cmdline come ...

/usr/bin/myprog\0foo bar\0baz 

completa indovinare qui, io non riesco a trovare spazi in una delle mie scatole di Linux.

+1

Ciao. Come hai detto, gli spazi sono usati per separare le parole nello stesso termine, questo era quello che mi aspettavo, ma ho accesso a una macchina che usa gli spazi per separare anche i termini. Era un Ubuntu, non so quale versione. – ryotakatsuki

10

Il /proc/PID/cmdline è sempre separati da caratteri NUL.

Per comprendere gli spazi, eseguire questo comando:

cat -v /proc/self/cmdline "a b" "c d e" 

EDIT: Se davvero vedere spazi dove non ci dovrebbe essere alcuna, forse il vostro eseguibile (volontariamente o involontariamente) scrive argv[], o sta utilizzando setproctitle() ?

Quando il processo viene avviato dal kernel, cmdline è NUL-separati, e la kernel code simply copies l'intervallo di memoria in cui argv[] era in fase di avvio di processo nel buffer di uscita quando si legge /proc/PID/cmdline.

+0

Come ho detto sopra, mentre spiegavo la "soluzione" a un collega, mi sono reso conto che le sue cmdlines non si comportavano come mi aspettavo. Entrambi usiamo Ubuntu, quindi non so se si tratta di un comportamento che può essere configurato o dipende dal kernel utilizzato. – ryotakatsuki

+0

Questo è sbagliato. A volte ci sono spazi che separano gli argomenti - cioè è tutto in argv [0]. Lo so perché ho visto questo. – camh

+0

La mutabilità del vettore argomento dal programma è il motivo per cui ho contestato la tua affermazione. Se non avessi detto "sempre" e l'avessi enfatizzato, non avrei commentato. – camh

2

Dai un'occhiata alla mia risposta here. Copre ciò che ho trovato cercando di farlo da solo.

Modifica: Dai un'occhiata al thread this su debian-user per uno script bash che fa del suo meglio per fare ciò che vuoi (cerca la versione 3 dello script in quel thread).

+0

Ciao. Sto già facendo qualcosa di simile ai processi di tracciamento per il suo percorso, leggendo il link simbolico exe, ma il grosso problema è ottenere il nome dell'eseguibile nel cmd. Voglio dire, di solito, quando ti riferisci a un eseguibile di un processo, dici: "Voglio il PID di emacs" così ti aspetti di trovare "emacs", non "/ usr/bin/emacs22-gtk" come punta l'exe. Quello che non ho preso in considerazione è la stringa '(Deleted) riportata da readlink. Se potessi dividere correttamente le informazioni in cmdline potrei mescolare le sue informazioni con quella fornita da 'exe'. In ogni caso, sembra che non ci sia un modo evidente :). Grazie! – ryotakatsuki

+0

Ho aggiunto un collegamento a un thread in cui ho pubblicato uno script che contiene la mia implementazione. Non gestisce un nome eseguibile con uno spazio, ma è raro (così raro che non ne abbia mai visto uno) – camh

+0

Uaaa ... Ottimo lavoro, grazie! – ryotakatsuki

14

uso strings

$ cat /proc/self/cmdline | strings -1 
cat 
/proc/self/cmdline 
6

Usa

cat /proc/2634/cmdline | tr "\0" " " 

per ottenere i args separate da spazi vuoti, come si farebbe vedere su una riga di comando.

+0

Non è necessario utilizzare "cat + tr" quando "tr" può farlo da solo, vedere la risposta a @ hek2mgl. –

4

Gli argomenti della riga di comando in /proc/PID/cmdline sono separati da byte null. È possibile utilizzare tr per sostituirli con nuove righe:

tr '\0' '\n' < /proc/"$PID"/cmdline