Czytaj dzienniki z jednego procesu podczas uruchamiania niektórych poleceń

10

Mam usługę, która produkuje dzienniki w pliku logs.log.

Mam inne polecenie, które współdziała z tą usługą. Powiedzmy, że to trochę foo.sh.

Potrzebuję wyciąć i zapisać dzienniki logs.logdokładnie podczas foo.shpracy. Innymi słowy, potrzebuję tej części dzienników usługi, gdy wchodzi ona w interakcje z moimi foo.sh(więc nie dbam o foo.shdzienniki).

Spodziewałbym się, że to polecenie załatwi sprawę, ale kontynuuje czytanie pliku po foo.shzakończeniu:

> foo.sh | tail -f logs.log > foo_part.log

Czy jest jakiś fajny sposób na wykonanie tej sztuczki?

Andremoniy
źródło

Odpowiedzi:

12

Jest to dość proste, wysyłając procesy w tle do, cóż, tła:

foo.sh &
mypid=$!
tail -f /path/to/logs.log > /path/to/partial.log &
tailpid=$!
wait $mypid
kill -TERM $tailpid

$!Przechwytuje PID ostatniego zadania wysłany do pracy w tle, więc możemy waitna skrypcie do końca, a następnie killten tailproces, kiedy nie jest już potrzebna.

DopeGhoti
źródło
3
niesamowita odpowiedź, nauczyłem się dziś czegoś nowego
Miguel Mota
7

Ta wersja też może to zrobić (tak myślę):

( tail -f logs.log >foo_part.log &
foo.sh&
wait $! && kill %1 ) 

Zauważ, że% 1 uderzy w pierwszy proces w tle w podpowłoce

Luciano Andress Martini
źródło
Osobiście wolę przechwytywać wyraźne PID niż korzystać z listy zadań, ponieważ coraz bardziej złożona implementacja tego może spowodować, że w tle będzie znajdować się więcej niż jedno zadanie i kill %1może dojść do złego celu.
DopeGhoti
1
Ponieważ użyłem nawiasów podpowłoki, więc% 1 odniesie się do pierwszego zadania w podpowłoce (ale nie jestem tego pewien dla wszystkich powłok). Oczywiste jest, że twoje rozwiązanie jest bardziej kompletne i funkcjonalne dla większej liczby przypadków, ale myślę, że może zrobić to, czego potrzebuje użytkownik .... Innym problemem jest to, że moja wersja wymaga przynajmniej utworzenia foo_part.log za pomocą dotyku, twoja wersja nie.
Luciano Andress Martini