(Nie)znajomość własnego warsztatu

Gdy pracuję w systemie Linux i korzystam z mojego ulubionego klienta Bittorrent - Azureusa, często zachodzi potrzeba potraktowania tego programu poleceniami renice i ionice, żeby zwiększyć responsywność systemu, która mogła ucierpieć przez działanie złożonej Jav’owej aplikacji. Warto było w tym celu napisać sobie prosty skrypt. Pojawił się tutaj problem pobrania PID’u procesu na podstawie jego nazwy. Nie zagłębiając się specjalnie w naturę problemu (co okazało się błędem - o tym za chwilę) stworzyłem własne rozwiązanie tego problemu w ten sposób:

ps ax | grep "java.*Azureus" | awk {$0 = gensub(/legacy/blog/^ +/,"", "g", $0); print $1; exit}'

Dla zainteresowanych krótkie wytłumaczenie działania tej komendy:

  • ps ax - wyświetla listę wszystkich procesów użytkownika, również tych, które nie posiadają konsoli. Na początku każdego wiersza, tuż po spacji, jest szukany przeze mnie PID. Gdzieś pod koniec jest “command line” którym uruchomiono proces.

  • Odnajduję wiersz z procesem Jav’y, szukając słowa “java”, następnie dowolnej liczby dowolnych znaków, następnie słowa “Azureus”. Wzorzec ten “łapie” wiersz z procesem, którego szukam.

  • Następnie trzeba się jakoś pozbyć tej nieszczęsnej spacji na początku. Niestety prostym poleceniem cut nie dało rady, więc sięgnąłem po potężny AWK, który nadaje się idealnie, ponieważ przetwarza wierszami i od razu dzieli wiersz na rekordy. W “miniprogramie” AWK usuwam spację z początku wiersza “łapiąc” ją wyrażeniem regularnym “/^ +/” i usuwając. Następnie wypisuję pierwszy rekord wiersza, czyli szukany PID.

Jak widać powyższe rozwiązanie wbrew pozorom wykorzystuje sporo różnych pomysłów i w gruncie rzeczy nie wygląda na najprostsze. W tym momencie dochodzę do refleksji, która jest przedmiotem tego wpisu: otóż ktoś już wcześniej zauważył, że w życiu często zachodzi potrzeba znalezienia PID’u procesu po jego nazwie i wymyślono do tego oddzielne polecenie:

pgrep -f Azureus

Efekt jego działania jest dokładnie taki sam jak polecenia, które ułożyłem wcześniej. Wniosek z tego jest taki, że jeżeli zabieramy się za tworzenie własnego rozwiązania jakiegokolwiek problemu informatycznego (a może wcale nie tylko informatycznego), warto sprawdzić najpierw czy w danej chwili już nie dysponujemy narzędziami, którymi możemy ten problem rozwiązać natychmiast. Myślę, że przykładów podobnych, niezwykle użytecznych i mało znanych poleceń oraz funkcjonalności powłoki systemu Linux jest więcej, chociażby takie jak: watch, stat, column, reset czy mechanizmy zwane “event designator” albo “brace expansion”.

PS. Dla formalności dodam jeszcze, że podany wyżej “miniprogram” AWK też jest nadmiernie skomplikowany, bo okazuje się, że gensub nie jest potrzebny, samo "print $1" wystarczy :)