12.09
Ciężka jest praca admina – szczególnie w okolicach godziny 17:00, gdy programiści kończą pracę i idą do domu, ale przed wyjściem wystawią jeszcze ticket treści:
Cześć,
Na serwerze developerskim działa sobie beta projektu, który na jutro musimy odpalić na produkcji. Projekt możesz zobaczyć pod adresem:
http://10.0.0.100:6666
Tak jak chciałeś, wszystko jest ładnie opisane, projekt jest w svn. Nawet, gdy zajrzysz do environment.rb to będziesz miał listę wszystkich gemów, z jakich korzysta projekt – już nie musisz się na nas wkurwiać :]
Słodko. Klienci biorą sobie do serca moje uwagi i ułatwiają mi pracę. Z uśmiechem na twarzy łączę się VPN-em do ich sieci, odpalam wskazany adres. Pięknie projekt działa. No to teraz loguję się na maszynę… mały lag – pewnie znowu ktoś u nich torrenty na noc zostawił, będę musiał wyciąć …. o jestem :)
No i nagle bęc! Ale gdzie kurka ten projekt leży? Fuck… nie napisali. Pewnie już się domyślacie o czym będzie dzisiejszy wpis – jak znaleźć katalog z projektem (current dir) mając tylko dane przekazane w tickecie.
Na wstępie kilka założeń:
- projekt jest odpalony w ruby (rails) przy pomocy zwykłego script/server
- skupimy się na dwóch systemach operacyjnych: linux oraz freebsd
- programiści trzymają projekty w katalogach o nazwach: dupa, kapitan_bomba, xxx, beta,
No dobrze, wiemy że projekt jest odpalony i jak sprawdziliśmy działa. Znamy przybindowany jego adres IP (10.0.0.100) oraz port TCP (6666). Te informacje to wszystko co mamy. Wiemy, że domyślny serwer railsów odpala aplikacje na porcie TCP 3000, jeśli chcemy inny adres to musimy skorzystać z parametru -p i określić numer portu TCP, który chcemy wykorzystać.
Sprawdźmy co powie nam ps:
root@mandarynka:/root# ps a | grep 6666 9596 pts/1 S+ 0:00 grep 6666 29798 pts/0 Sl+ 0:04 ruby ./script/server -p 6666
Dobra mamy PID procesu (29798), więc jesteśmy w domu. Teraz jak sprawdzić katalog (current dir), gdy korzystamy z linuksa. Możliwości mamy kilka:
- lsof
- katalog proc
- pwdx
- gdb
Zacznijmy od lsof – jest to program, który zrzuca nam informacje o otwartych plikach w systemie. Gdy wywołamy ten program bez żadnych parametrów, to zostanie nam wyrzucona bardzo pokaźna (wielkość zależna od wielkości systemu) lista otwartych plików wraz z informacjami o korzystających z nich procesach. Nas jednak interesuje tylko proces o określonym pidzie – w tym wypadku 29798.
root@mandarynka:/root# lsof -p 29798 | grep -B 1 cwd COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME ruby 29798 jacek cwd DIR 8,1 4096 4082438 /var/apps/projekty/deszczowy_grudzien
Bingo – kto by wpadł na pomysł, że projekt będzie znajdował się w katalogu /var/apps/projekty/deszczowy_grudzien? :)
Druga opcja – katalog proc. W linuksie mamy podmontowany specjalny katalog (/proc), w którym mamy wszystkie informacje o stanie systemu, jego sprzęcie itp. Gdy wejdziemy do katalogu proc to zobaczymy wiele katalogów nazwanych liczbami oraz kilkanaście plików. Te katalogi nazwane liczbami to zmapowane do plików procesy – liczba oznacza PID procesu. W każdym takim katalogu jest plik symlink o nazwie cmd, który wskazuje na aktualny katalog. Zobaczmy jak to działa w praktyce:
root@mandarynka:/root# ls -lh /proc/29798/cwd lrwxrwxrwx 1 jacek jacek 0 2009-12-08 22:52 /proc/29798/cwd -> /var/apps/projekty/deszczowy_grudzien
Kolejna opcja w systemach linuksowych – pwdx:
root@mandarynka:/root# pwdx 29798 29798: /var/apps/projekty/deszczowy_grudzien
No i kolejna opcja – najbardziej hardcorowa, ale cholera wie na jakiego linuksa trafimy i jakie oprogramowanie będzie tam zainstalowane. Ja wychodzę z założenia, że lepiej mieć jeden as więcej w rękawie, niż mniej :)
No to jedziemy:
root@mandarynka:/root# gdb GNU gdb 6.8-debian .... This GDB was configured as "x86_64-linux-gnu". (gdb) attach 29798 Attaching to process 29798 Reading symbols from /usr/bin/ruby1.8...(no debugging symbols found)...done. Reading symbols from /usr/lib/libruby1.8.so.1.8...(no debugging symbols found)...done. Loaded symbols for /usr/lib/libruby1.8.so.1.8 Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done. [Thread debugging using libthread_db enabled] .... .... (gdb) set $buf = "" [Switching to Thread 0x7fc3a054c6f0 (LWP 29798)] (gdb) call (char *)getcwd($buf, 128) $1 = 0x3a4a860 " /var/apps/projekty/deszczowy_grudzien" (gdb) detach Detaching from program: /usr/bin/ruby1.8, process 29798 (gdb) quit
No i pięknie. Mamy ten nasz katalog, ale w linuksie. Co jeśli mamy FreeBSD? Tam nie ma katalogu /proc, domyślnie lsof nie jest zainstalowany. Jest gdb, ale jest też prostsza metoda – narzędzie o skromnej nazwie procstat. Nie mam pod ręką żadnej freebsd z odpalonym projektem w railsach przez script/server, więc sprawdźmy sobie current dir innego procesu – powiedzmy odpalmy sobie vima:
galerianka# ps aux | grep vim root 67884 0.0 1.5 38744 7508 p0 I+ 11:08PM 0:00.08 vim
Teraz sprawdźmy jaki jest current dir tego procesu (PID = 67884)
galerianka# procstat -f 67884 galerianka# procstat -f 67884 PID COMM FD T V FLAGS REF OFFSET PRO NAME 67884 vim cwd v d -------- - - - /tmp 67884 vim root v d -------- - - - / 67884 vim 0 v c rw------ 9 70919 - - 67884 vim 1 v c rw------ 9 70919 - - 67884 vim 2 v c rw------ 9 70919 - -
Jak widzimy w kolumnie gdzie FD = cwd mamy /tmp <- to jest właśnie nasz current dir :)
Mam nadzieję, że już nikt nie będzie musiał się zmagać z przedstawionym w powyższym wpisie problemem – a jeszcze lepiej, jak Wam klienci będą pięknie opisane tickety wystawiać – ale wtedy nie będzie takich wpisów, ponieważ jak to mówią “potrzeba matką wynalazków” ;)
PS. Oczywiście, jeśli znacie jeszcze jakieś metody zdobycia current_dir procesu to piszcie – zaktualizuje wtedy ten wpis :)
Dzieki za ciekawe informacje
[...] źródło: blog.y3ti.pl Follow us on Twitter 26 śledzących RSS Feed 218 czytelników Jak znaleźć “current dir” procesu? 1 głosuj! Jak za pomocą ogólnodostępnych narzędzi uniksowych odnaleźć current_dir [...]