2009-10-18 16 views
9

Ich versuche, die Cmdline eines Prozesses unter Linux zu teilen, aber es scheint, ich kann nicht darauf verlassen, dass es durch '\ 0' Zeichen getrennt wird. Weißt du, warum manchmal das Zeichen '\ 0' als Trennzeichen verwendet wird und manchmal ein normales Leerzeichen ist?Wie zu analysieren/proc/pid/cmdline

Kennen Sie andere Möglichkeiten, den Namen der ausführbaren Datei und den Pfad dazu abzurufen? Ich habe versucht, diese Informationen mit "PS" zu erhalten, aber es gibt immer die vollständige Befehlszeile zurück und der ausführbare Name wird abgeschnitten.

Danke.

Antwort

3

Ein Schuss in die Dunkelheit, aber ist es möglich, dass \0 trennt Begriffe und Leerzeichen sind Wörter innerhalb eines Begriffs zu trennen? Zum Beispiel

myprog "foo bar" baz 

erscheinen mag in /proc/pid/cmdline als ...

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

komplette Vermutung hier kann ich keine Leerzeichen auf einer meiner Linux-Boxen zu finden scheinen.

+1

Hallo. Wie Sie erwähnen, werden Leerzeichen verwendet, um Wörter in demselben Begriff zu trennen, das war, was ich erwartet hatte, aber ich habe Zugriff auf eine Maschine, die Leerzeichen verwendet, um auch Begriffe zu trennen. Es war ein Ubuntu, ich weiß nicht welche Version. – ryotakatsuki

10

Die /proc/PID/cmdline ist immer von NUL-Zeichen getrennt.

Räume zu verstehen, führen Sie diesen Befehl:

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

EDIT: Wenn Sie wirklich Räume sehen, wo es nicht, vielleicht die ausführbare Datei (absichtlich oder unabsichtlich) sein sollte, schreibt argv[] oder setproctitle() verwendet ?

Wenn der Prozess vom Kernel gestartet wird, cmdline ist NUL-getrennt und die kernel code simply copies der Bereich des Speichers, wo argv[] bei Prozessstart in den Ausgabepuffer war, als Sie /proc/PID/cmdline lesen.

+0

Wie ich oben sagte, während ich einem Mitarbeiter die "Lösung" erklärte, bemerkte ich, dass seine Cmdlines sich nicht so verhielten, wie ich es erwartet hatte. Wir beide benutzen Ubuntu, daher weiß ich nicht, ob dies ein Verhalten ist, das konfiguriert werden kann oder vom verwendeten Kernel abhängt. – ryotakatsuki

+0

Das ist falsch. Manchmal gibt es Leerzeichen, die die Argumente trennen - also alles in argv [0]. Ich weiß das, weil ich das gesehen habe. – camh

+0

Die Veränderlichkeit des Argumentvektors durch das Programm ist der Grund, warum ich Ihrer Aussage widersprochen habe. Wenn Sie nicht "immer" gesagt und es betont hätten, hätte ich nicht kommentiert. – camh

2

Werfen Sie einen Blick auf meine Antwort here. Es deckt ab, was ich gefunden habe, als ich das selbst versucht habe.

Bearbeiten: Werfen Sie einen Blick auf this Thread auf Debian-Benutzer für ein Bash-Skript, das sein Bestes versucht, was Sie wollen (suchen Sie nach Version 3 des Skripts in diesem Thread).

+0

Hallo. Ich mache schon etwas ähnliches, um Prozesse nach seinem Pfad zu verfolgen, den exe symlink zu lesen, aber das große Problem ist, den ausführbaren Namen in den cmd zu bekommen. Ich meine, normalerweise, wenn Sie sich auf eine ausführbare Datei beziehen, sagen Sie: "Ich möchte die PID von emacs", also erwarten Sie, "Emacs" zu finden, nicht "/ usr/bin/emacs22-gtk", wie die exe darauf hinweist. Was ich nicht berücksichtigt habe, ist die '(Gelöschte)' Zeichenfolge, die von readlink gemeldet wurde. Wenn ich die Informationen in cmdline richtig aufteilen könnte, könnte ich ihre Informationen mit denen von 'exe' kombinieren. In jedem Fall scheint es keinen offensichtlichen Weg zu geben :). Vielen Dank! – ryotakatsuki

+0

Ich habe einen Link zu einem Thread hinzugefügt, in dem ich ein Skript veröffentlicht habe, das meine Implementierung enthält. Es wird nicht mit einem ausführbaren Namen mit einem Platz darin umgehen, aber sie sind selten (so selten, dass ich noch nie einen gesehen habe) – camh

+0

Uaaa ... Tolle Arbeit, Danke! – ryotakatsuki

14

Verwendung strings

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

Verwenden

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

die args durch Leerzeichen getrennt zu erhalten, wie Sie es in einer Befehlszeile sehen würde.

+0

Keine Notwendigkeit, "cat + tr" zu verwenden, wenn "tr" allein es tun kann, siehe @ hek2mgl antwort. –

4

Die Befehlszeilenargumente in /proc/PID/cmdline sind durch Nullbytes getrennt. Sie können tr verwenden, um sie durch neue Zeilen zu ersetzen: