2009-10-18 13 views
9

Próbuję podzielić cmdline procesu na Linuksie, ale wydaje się, że nie mogę na nim polegać, aby oddzielić go od znaków "\ 0". Czy wiesz, dlaczego czasami znak "\ 0" jest używany jako separator, a czasami jest to zwykła przestrzeń?Jak parsować/proc/pid/cmdline

Czy znasz inne sposoby pobierania nazwy pliku wykonywalnego i ścieżki do niego? Próbuję uzyskać te informacje za pomocą "ps", ale zawsze zwraca pełną linię poleceń, a nazwa pliku wykonywalnego jest obcięta.

Dzięki.

Odpowiedz

3

Strzał w ciemność, ale czy możliwe jest, że \0 oddziela terminy i spacje oddzielające słowa w obrębie terminu? Na przykład,

myprog "foo bar" baz 

może pojawić się jako /proc/pid/cmdline ...

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

Kompletna przypuszczenie tutaj, nie mogę wydawać się znaleźć żadnych spacji na jednym z moich skrzynek Linux.

+1

Witam. Jak wspomniałeś, spacje są używane do oddzielania słów w tym samym terminie, to było to, czego oczekiwałem, ale mam dostęp do maszyny, która używa spacji również do oddzielnych warunków. To był Ubuntu, nie wiem, które wydanie. – ryotakatsuki

10

/proc/PID/cmdline jest zawsze zawsze oddzielona znakami NUL.

Aby zrozumieć spacje, należy wykonać polecenie:

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

EDIT: Jeśli naprawdę zobaczyć miejsca, gdzie nie powinno być w ogóle, być może plik wykonywalny (umyślnie lub nieumyślnie) pisze do argv[] lub korzysta setproctitle() ?

Gdy proces jest uruchamiany przez jądro, CmdLine jest NUL-rozdzielono i kernel code simply copies zakres pamięci gdzie argv[] było przy starcie procesu do bufora wyjściowego, kiedy czytasz /proc/PID/cmdline.

+0

Jak wspomniałem powyżej, gdy wyjaśniałem "rozwiązanie" współpracownikowi, zdałem sobie sprawę, że jego cmdlines nie zachowywały się tak, jak oczekiwałem. Oboje używamy Ubuntu, więc nie wiem, czy jest to zachowanie, które można skonfigurować, czy też zależy od używanego Kernela. – ryotakatsuki

+0

To jest złe. Czasami są spacje oddzielające argumenty - tzn. Wszystko jest w argv [0]. Wiem to, ponieważ widzę to. – camh

+0

Zmienność wektora argumentu przez program jest powodem, dla którego sprzeciwiłem się twojemu stwierdzeniu. Gdybyś nie powiedział "zawsze" i podkreślił to, nie skomentowałbym. – camh

2

Spójrz na moją odpowiedź here. Obejmuje to, co znalazłem, próbując zrobić to sam.

Edycja: zajrzyj do wątku this wątku debian-user dla skryptu basha, który stara się jak najlepiej zrobić to, czego potrzebujesz (poszukaj wersji 3 skryptu w tym wątku).

+0

Witam. Już robię coś podobnego do śledzenia procesów po ścieżce, czytając dowiązanie symboliczne exe, ale dużym problemem jest uzyskanie nazwy pliku wykonywalnego w cmd. Zazwyczaj, kiedy odwołujesz się do pliku wykonywalnego procesu, mówisz: "Chcę PID emacsa", więc spodziewasz się znaleźć "emacs", a nie "/ usr/bin/emacs22-gtk" jako punkty exe. To, czego nie brałem pod uwagę, to ciąg "(usunięty)" zgłaszany przez readlink. Gdybym mógł poprawnie podzielić informacje w cmdline, mógłbym wymieszać jego informacje z danymi dostarczonymi przez "exe". W każdym razie wydaje się, że nie ma ewidentnego sposobu :). Dzięki! – ryotakatsuki

+0

Dodałem link do wątku, w którym opublikowałem skrypt zawierający moją implementację. Nie będzie obsługiwać nazwy pliku wykonywalnego zawierającego spację, ale są one rzadkie (tak rzadkie, że nigdy ich nie widziałem). – camh

+0

Uaaa ... Świetna robota, dzięki! – ryotakatsuki

14

użycie strings

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

Zastosowanie

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

uzyskać args oddzielone spacjami, tak jak widać to na linii poleceń.

+0

Nie trzeba używać "cat + tr", gdy może to zrobić sam użytkownik "tr", zobacz odpowiedź @ hek2mgl. –

4

Argumenty wiersza poleceń w /proc/PID/cmdline są oddzielone bajtami zerowymi. Możesz użyć tr, aby zastąpić je nowymi liniami:

tr '\0' '\n' < /proc/"$PID"/cmdline 
Powiązane problemy