Nagrywam przy pomocy shella audycje z dwóch różnych strumieni. Robię to przy użyciu następujących skryptów, które uruchamiają o wybranych godzinach odpowiednie wpisy w cronie:
Nagrywanie zatrzymuję uruchamianym przez cron o odpowiednich porach skryptem:
#!/bin/bash
killall -s TERM wget
Mam jednak pewien problem, gdy pokrywają się czasy nagrywania obu audycji. Wówczas muszę kończyć nagranie audycji krótszej w momencie końca audycji dłuższej, by nie obciąć tej drugiej.
W jaki sposób, używając skryptu kill, kończyć działanie poszczególnych skryptów, a nie wszystkich?
Nieco trzeba zmodyfikować, aby uwalać wget po PIDzie.
wget -c -nc --waitretry=1 --tries=0 http://stream4.nadaje.com:9240/prw -O /home/rostov/JW/$NAZWAPLIKU.mp3 -o /home/rostov/JW/log/$NAZWAPLIKU.log 2>&1 & PID1=`echo $!`
wget -c -nc --waitretry=1 --tries=0 http://stream4.nadaje.com:9230/rwkultura -O /home/rostov/JW/$NAZWAPLIKU.mp3 -o /home/rostov/JW/log/$NAZWAPLIKU.log 2>&1 & PID2=`echo $!`
"QUIT":
DLA pierwszego WGET:
kill $PID1
DLA drugiego WGET:
kill $PID2
Słowem wyjaśnienia: 2>&1 (przekierowuje standardowe wyjście błędów na standardowe wyjście) & (przenosi proces w tryb “tła” / background) PID1=`echo $!` (podstawia pod zmienną PID1 numer PID procesu wget aktualnie uruchomionego w tle)
kill $PID1 (TERM (terminate)) kill $PID2 (analogicznie do w. w.)
Oczywiście nie stoi nic na przeszkodzie, żeby w każdej chwili sprawdzić procesy zadań wget w tle.
W konsoli wpisujesz w takim wypadku jobs pokazuje Ci zadania w tle, potem fg NUMER_ZADANIA , żeby “wydobyć na wierzch” jak chcesz przerwać zadanie to po wydobyciu Ctrl+C
jeżeli z powrotem wysłać w tło to Ctrl+Z, a następnie: bg NUMER_ZADANIA
i wtedy działa sobie dalej w tle. jobs również wypisuje Ci PIDy zadań w tle więc możesz użyć kill %NUMER_ZADANIA i to będzie równoznacznie z jego zakończeniem.
W cron wywolujesz 2 zadania. Czy skrypt napiszesz jeden czy dwa, to już zależy od Ciebie. Możesz zrobić tak jak napisal domker lub napisać 2 osobne skrypty i killowac je po ich nazwie.
Gdy uruchomisz skypt1.sh i sprawdzisz sobie procesy poleceniem ps, to zobaczy uruchomiony skrypt w procesach i jego nazwę.
Jeśli skrypt nagrywający uruchamiasz o konretnej godzinie i o konretnej go ubijasz oraz uruchamiasz jeden po drugim, to masz jeszcze prostsze rozwiązanie.
rw.sh - mój skrypt nagrywający.
Kiedy o 19:30 zalogowałem się przez ftp do katalogu, do którego powinna trafiać nagrywana audycja, zauważyłem, że nagrywa się dalej. Co ciekawe — polecenie ps wcale nie wykazało, że uruchomiony jest ten skrypt, tylko 2 procesy: bash i ps. Jednak uruchomienie mojego starego skryptu killującego zatrzymało nagrywanie, więc skrypt uruchomiony był. Dlaczego killall nie zatrzymuje skryptu nagrywania i dlaczego w ogóle nie widać go w procesach?
Musisz wydać polecenie: ps -A, jeżeli chcesz zobaczyć wszystkie procesy z poziomu konsoli.
Zabijając skrypt powstrzymujesz niejako go przed wykonaniem kolejnych “kroków”.
Jeżeli z poziomu skryptu odpalony jest jakiś program np. wget to zabijesz skrypt, a program zostanie w procesach dalej uruchomiony.
Zapisz jako kill-test.sh, nadaj prawa uruchomieniowe, a następnie odpal w tle: ./kill-test.sh &
Potem Ctrl+C i spróbuj ubić: killall kill-test.sh
Skrypt oczywiście ubijesz i nie wykona się nic po kroku “sleep 120” po upłynięciu czasu 120 sekund, a w procesach dalej będziesz widział działający proces “sleep”, który ukończy swoją pracę po 120 sek., ale reszta skryptu się nie wykona.
@Domker
Zastosowałem Twoje rozwiązanie z ubijaniem procesu po PID. Skopiowałem linijki, które podałeś i wkleiłem do crontaba. Start ustawiłem na 19:00, kill na 19:05. Kiedy zajrzałem o 19:15, nagrywanie leciało dalej. Ponadto nagrywał się plik bez nazwy, samo rozszerzenie .mp3
A no nie działa to Cron widzę, że otwiera nowe sesje dla każdego zadania z osobna i zmienne się nie przenoszą. Nazwa pliku Ci się nie zrobiła, bo pewnie źle użyłeś w jednej linijce generowania nazwy.
Kurcze pieczone ten cron to upierdliwy jest.
Trzeba zmienić generowanie nazwy na:
NAZWAPLIKU=`date +\%d-\%m-\%Y_\%H-\%M`
Okazuje się, że w przypadku daty wszystkie parametry trzeba poprzedzić eskejpem “\”, bo inaczej w tym momencie jest błąd i polecenie dalej się nie wykonuje ze względu na “&&”.
W crontab “%” ma widocznie jakąś jeszcze rolę.