Zależy mi na zautomatyzowaniu wydruku plików postscriptowych przynoszonych do biura przez pewnego jegomościa.
Ów jegomość, zwany dalej Grafem Pruszyńskim, prosi mnie dość regularnie o drukowanie plików utoworzonych na Macowej wersji Quarka, sęk w tym że te postscripty drukują się nieprawidłowo. Zasadą natomiast jest, że po konwersji na PDF, za pomocą ps2pdf, ich wydruki są bez zarzutu.
Z powodu owej regularności i z wrodzonego lenistwa postanowiłem utworzyć na serwerze katalog, wyeksportowany po Sambie, do którego Graf Pruszyński będzie swoje pliki wrzucał, zaś drukowanie odbędzie się automatycznie. Katalog będzie podmountowany na stacji roboczej z Windows XP, co mam nadzieję na tyle ułatwi cały proces, że jegomość, który w komputerach jest mniej niż średnio kumaty, da sobie samodzielnie radę.
Moja głupota rozrasta się wprost proporcjonalnie do mojego wieku, w związku z czym zrozumienie, że inotify, który starałem się dłuższy czas uruchomić, już działa i sprawuje się zacnie, zajęło mi ze trzy dni.
Acha, muszę dodać o co chodzi...
inotify to dość świeży dodatek, wprowadzony ostatnio do jądra, mający zastąpić prymitywny i nieelegancki dnotify - program uruchamiający wybrane polecenie pod wpływem zmiany w obserwowanym katalogu. inotify napisany został przez Roberta Love.
Dlaczego wybrałem inotify? Szczerze mówiąc z jednego, jedynego powodu - z lenistwa. Wystarczyłby prawdopodobnie dnotify, ale ten nie potrafi informować, który plik się zmienił. Musiałbym więc w jakiś sposób poradzić sobie z utrzymywanie informacji o plikach w śledzonym katalogu, a po co, skoro robi to za mnie inotify?
Krok po kroku,w szybkim skrócie jak i co zrobiłem:
Podmieniłem kernel na najnowszy 2.6.13-rc6 bo już od rc3 jest w nim inotify, włączając go w sekcji File systems -> Inotify.
Zainstalowałem Gamin the File Alteration Monitor. Stworzyłem /etc/gamin/gaminrc
i na próbę uruchomiłem gam_server czyli demona Gamina.
Nie przeczytałem, jak zwykle, dokumentacji i tłukłem łbem w ścianę bo nie wiedziałem czemu mi gam_server po krótkiej chwili kończy działanie. W końcu grzebnąłem w doc-ach i znalazłem, że
Usually one also want to keep control over the server lifetime and not have it exit automatically after 30 seconds without connection, there is a command line flag --notimeout to gam_server for this.Uruchomiłem więc gam_server --notimeout i przystąpiłem do zabawy z Pythonem wg. podanego przez autora przykładu. Zadziałało, i bardzo milutkie to było przeżycie, polecam "opkodowywanie" Gamina w Pythonie
Na koniec zainstalowałem fileschanged (cóż za wyszukana nazwa[2]). Obsługa tego programu jest banalna. fileschanged posiada opcję -x umożliwiającą uruchomienie dowolnego programu lub skryptu i przekazanie do niego dwóch parametrów, pierwszy to rodzaj akcji jaka została wykonana na pliku, drugi to nazwa pliku z pełną ścieżką. Cytat z manuala:
-x PROG
--exec=PROG
Run PROG when file is altered (PROG action filename). Will execute `PROG' with the action and filename as parameters whenever that event occurs. Action is one of A, M, R, E or X. Filename is an absolutely specified path to the file.
Uruchomiłem więc fileschanged w taki sposób:
$ fileschanged -x ~/bin/inotify_alter.sh ~/ps
gdzie inotify_alter.sh to mój testowy skrypt, a ~/ps katalog w którym obserwuję zmiany.
Skrypt inotify_alter.sh wygląda tak:
#!/usr/bin/env bash
echo "Na pliku $2 została wykonana akcja $1"
echo "....................................."
Musi być prosty bo jego zadaniem jest tylko i wyłącznie sprawdzanie czy to działa. Działa! Skoro działa mogę napisać właściwy skrypt, równie prosty, który będzie robił to na czym mi najbardziej zależy.
Rozwiązaniem mojej bolączki jest zatem następujący skrypt, który nazwałem inotify_ps2pdf.sh:
#!/usr/bin/env bash
# skrypt ma za zadanie skonwertować plik Postscript na PDF i ew. druknąć
# korzysta z inotify (kernel) i Gamina (daemon)
# argumenty:
# $1 - akcja wykonana na pliku,
# $2 - pełna ścieżka z nazwą pliku.
if [ $1 = 'M' ]; then
TYP=`file -bi $2 | cut -d/ -f2`
if [ $TYP = 'postscript' ]; then
ps2pdf $2 $2.pdf
pdq -d xerox $2.pdf
rm $2 $2.pdf
fi
fi
Sprawdzam wyłącznie akcję typu "M" (modify) bo pojawia się ona w momencie utworzenia pliku lub jego modyfikacji. Potem sprawdzam za pomocą file czy plik zawiera Postscript, bo nie chcę mieć "krzaków" na drukarce gdy Graf Pruszyński będzie próbował drukować plik innego typu. Wreszcie używam Print Don't Queue [3]do wydruku. A na koniec kasuję pliki bezpowrotnie.
Teraz wystarczy dodać odpowiedni wpis do /etc/samba/smb.conf
, coś jak np.:
[ps]
comment = katalog do druku dla Grafa Pruszyńskiego
path = /home/paczor/ps
force user = paczor
force group = users
read only = No
create mask = 0665
directory mask = 0755
browseable = Yes
i zrestartować Sambę.
Na stacji z Windows zrobiłem plik typu batch, do podmounotywania katalogu ps
. Mogę oczywiście zrobić odpowiedni wpis w /etc/samba/smb.conf
, ale jak pisałem wyżej - nie chce mi się. [4].
Batch zawiera jedną linijkę:
Batch można uruchamiać automatycznie przy starcie Windows, można nawet wrzucić to jakoś w Rejestr ale mój opis pomija ten szczegół z powodu wyjaśnionego przed chwilą. Oczywiście, sam będę musiał mountować katalog ps automatycznie, ponieważ Grafa Pruszyńskiego ten problem może przerosnąć. Ale to już moja broszka.
net use z: \\gustlik\ps hasło /user:paczor
Wszytko pięknie zahasało, teraz pozostaje mi czekać na Grafa Pruszyńskiego i przygotować się na ewentualne kosmetyczne poprawki, bo w tym rozwiązaniu zbyt wiele zrobiłem założeń, nie próbując nawet przewidywać co Grafowi może przyjść do głowy. "Poskrobanie" personal-itcha zajęło mi w sumie kilka dni, ale tylko z powodu postępujące demencji ;-). Normalnemu człowiekowi ze średnio zaawansowaną wiedzą o Linuksie i Windows, nie powinno zabrać więcej jak pół godziny. Do rozwiązania pozostał problem powolnego, ale nieuniknionego zaśmiecania się katalogu ps, bo nie wolno wierzyć, że wrzucane będą doń wyłącznie pliki typu Postscript. Pominąłem zupełnie obsługę błędów, z założonego lenistwa, choć temat jest ciekawy bo przecież nic nie stoi na przeszkodzie by w skrypcie do drukowania ją umieścić, wykorzystując do informowania użytownika o błędach sambową funkcję wysyłania wiadomości do stacji z Windows. Ale bez przesady! :)
[1] Elmer Fudd, postać z "Looney Tunes", wymawiał zamiast "r", literę "ł", co wykorzystał mój kolega z pracy w Ogilvy, Bambini, i nazwał "Łogełem" pana Rogera Heathcote'a, dyrektora Ogilvy & Mathers, totalnego dupka. Powiedzenie o "solutions" to ulubiony tekst tego dupka. Żartowaliśmy z Bambinim, że Łogeł ukończył tylko jeden stopień kursów menedżerskich, i stąd jego skromna znajomość droidzkiego slangu.
[2] czepiam się ewidentnie bo przecież kiedyś się śmiałem z cytatu w "Unix Hater's Handbook, który brzmiał mniej więcej tak:
Even the commands that are pronounceable are idiosyncratic to say the least. How can one understand "biff"?. As people never tire of telling me, it is the name of a programmer's dog (but you'll note, just in case you thought this might help you to memorize the command, this name starts with a lower case letter). It comes coupled with a twee American icon, that is meaningless in the UK context. And there are other examples. Grep suggests to me that the author of this one had been reading too much Robert Heinlein (you grok?), or possibly --- and this is in fact quite likely --- was under the influence of psychotropic substances at the time. Unix seems to consist largely of arcanae which be learnt only by taking instruction direct from a priesthood who seem largely to be stuck in the anal-retentive stage. When yesterday's six-year olds take over Unix development (in four or five years) I fully expect to see new commands ldo, nja, mch and rfl. After turtles, dinosaurs. Will the command tRex devour your competitor's data?
[3] nie potrafiłem zmusić CUPS-a do drukowania pliterek z Mozilli, pewnie czegoś nie doczytałem, ale gdy miałem już zacząć czytać moje oko padło na PDQ i postanowiłem to sprawdzić. No i nie dość, że drukuje pliterki, przy pomocy pocesti, to jeszcze jest jakiś taki prosty i ładny ten PDQ. Dlatego przy nim pozostanę. Poza tym całkiem niedawno doczytałem do końca enuncjacje Erica S. Raymonda pt. "The Luxury of Ignorance: An Open-Source Horror Story" i w pełni zgadza się to z moimi doświadczeniami. Ale o systemie drukowania w Linuksie pozwolę sobie kiedyś napisać więcej i nieprzyjemniej. Bo to badziew!
[4] no dobra! Można wpisać do /etc/samba/smb.conf
linijki wskazujące na skrypt logowania, np:
i w skrypcie default.bat umieścić na przykład taki wpis:
logon path = \\%L\Profiles\%u
logon script = default.bat
@echo off
net use z: \\gustlik\ps hasło /user:paczor /persistent:no