Napisałem skrypt powłoki do monitorowania katalogu za pomocą narzędzia inotifywait programu inotifyt-tools. Chcę, aby ten skrypt działał nieprzerwanie w tle, ale chcę też móc go zatrzymać w razie potrzeby.
Aby działał nieprzerwanie, użyłem while true
; lubię to:
while true;
do #a set of commands that use the inotifywait utility
end
Zapisałem go w pliku /bin
i sprawiłem, że jest wykonywalny. Aby działał w tle, użyłem nohup <script-name> &
i zamknąłem terminal.
Nie wiem jak zatrzymać ten skrypt. Przejrzałem tutaj odpowiedzi i bardzo ściśle powiązane pytanie tutaj .
AKTUALIZACJA 1: Na podstawie odpowiedzi @InfectedRoot poniżej udało mi się rozwiązać problem przy użyciu następującej strategii. Pierwsze użycie
ps -aux | grep script_name
i użyj, sudo kill -9 <pid>
aby zabić procesy. Potem musiałem pgrep inotifywait
i użyłem sudo kill -9 <pid>
ponownie do zwrotu identyfikatora.
To działa, ale myślę, że to niechlujne podejście. Szukam lepszej odpowiedzi.
AKTUALIZACJA 2: Odpowiedź polega na zabiciu 2 procesów . Jest to ważne, ponieważ uruchomienie skryptu w wierszu polecenia inicjuje 2 procesy, 1 sam skrypt i 2 proces inotify .
-9
opcjikill
i użycie po prostukill
usunie z niej bałagan.-9
opcja byłaby całkowitakill
. : Pkill
to ty prefiks pgid z minusem:kill -- -<pgid>
,kill -9 -<pgid>
itdOdpowiedzi:
Aby ulepszyć, użyć
killall
, a także połączyć polecenia:Lub rób wszystko w jednym wierszu:
źródło
Error: no process
powinno oznaczać, że już go zabiłeś. Możesz to przetestować, otwierając dwa inne programy, takie jak VLC i Geany , i wypróbowując go razem z nimi.grep -v grep
, zamieniając sięgrep script_name
wgrep -e "[s]cript_name"
.Wyświetl listę zadań w tle za pomocą
# jobs
Następnie wybierz poprzednią liczbę zadań i uruchom
przykład
przyniesie na pierwszy plan.
Następnie zabij go za pomocą CTRL + C lub łatwiejszego sposobu znalezienia PID skryptu za pomocą
Następnie zabij za pomocą pid
źródło
jobs
polecenie naprawdę wyświetlało uruchomione zadania tylko w powłoce. Kiedy zamknąłem pewne okno terminala, jedynym sposobem na uzyskanie do nich dostępu było wejścieps
(patrz powyżej). Na pewno nie wymyślisz tego.Możesz użyć
ps
+grep
lub,pgrep
aby uzyskać nazwę procesu / pid ; później użyjkillall
/,pkill
aby zabić nazwę procesu lub użyj,kill
aby zabić pid. Wszystkie poniższe powinny zadziałać.Najważniejsze jest to, że powinieneś upewnić się, że zabijasz tylko te procesy, które chcesz zabić.
pkill
/pgrep
pasuje do wzorca zamiast do dokładnej nazwy , więc jest bardziej niebezpieczny; tutaj-x
dodaje się, aby dopasować dokładną nazwę.Ponadto, gdy używasz
pgrep
/pkill
możesz potrzebować-f
aby dopasować pełny wiersz poleceń (podobnie jakps aux
robi)-a
aby wydrukować także nazwę procesu.źródło
pgrep
/pkill
. Jeśli to nadal nie działa, możesz spróbowaćpgrep
bez opcji -x. Zasadniczo nie sądzę, że dobrze jest zabijać proces w ramach jednego wiersza polecenia bez sprawdzania, czy inne procesy są dopasowane.Jak zapewne można stwierdzić, istnieje wiele sposobów na zrobienie tego.
Jeśli chodzi o twoją „AKTUALIZACJĘ # 2” - ogólnie mówiąc, zakończenie dowolnego procesu w hierarchii rodzic-dziecko spowoduje na ogół zakończenie wszystkich powiązanych procesów. Ale istnieje wiele wyjątków od tego. Najlepiej, jeśli chcesz zakończyć ostatnie „dziecko” w drzewie procesów, a następnie rodzice (rodzice) tego dziecka powinni wyjść, jeśli nie mają innych zadań do uruchomienia. Ale jeśli zabijesz rodzica, sygnał powinien zostać przekazany dzieciom, gdy rodzic umiera, a dzieci powinny również wyjść - ale są przypadki, w których procesy potomne mogą zignorować sygnał (za pośrednictwem pułapek lub podobnych mechanizmów) i mogą kontynuować uruchomienie zostanie odziedziczone przez proces „init” (lub podobny). Ale ten temat zachowania procesu może się skomplikować i po prostu zostawię go tam ...
Jedną z metod, które lubię, jeśli nie chcę używać skryptu sterującego (opisanego poniżej), jest użycie narzędzia „screen” do uruchomienia i zarządzania procesem. Komenda „screen” jest pełna funkcji i opanowanie jej może trochę potrwać. Zachęcam do przeczytania strony podręcznika „screen”, aby uzyskać pełne wyjaśnienie. Szybki przykład uruchomienia procesu w tle to polecenie:
screen -d -m / ścieżka / do / program
To rozpocznie „/ path / to / program” w sesji „screen”.
Możesz zobaczyć swoją uruchomioną sesję za pomocą polecenia:
screen -ls
W każdej chwili możesz ponownie połączyć się z uruchomionym programem za pomocą polecenia:
screen -r
A następnie po prostu zakończ go ^ C lub czymkolwiek.
Oprócz piękna, jakim jest możliwość ponownego połączenia i rozłączenia się z procesem do woli, „ekran” przechwytuje wszystkie standardowe () stdout (), które może wytworzyć Twój program.
Ale moje osobiste preferencje w tych sprawach to mieć program kontrolny, który zarządza uruchamianiem i zatrzymywaniem procesu. Może to być nieco skomplikowane i wymaga pewnie skomplikowanych skryptów. I jak każdy skrypt, istnieją dziesiątki dobrych sposobów na zrobienie tego. Podałem przykładowy przykład metody, której rutynowo używam do uruchamiania i zatrzymywania aplikacji. Jeśli twoje zadanie jest proste, możesz wstawić je bezpośrednio do skryptu sterującego - lub możesz wywoływać ten skrypt sterujący w innym programie zewnętrznym. Należy zauważyć, że ten przykład nie jest kompleksowy pod względem zarządzania procesem. Pominąłem możliwość takich scenariuszy, jak: upewnienie się, że skrypt nie jest już uruchomiony, gdy korzystasz z opcji „start”, sprawdzanie, czy działający PID jest tak naprawdę procesem, który rozpocząłeś (np. Twój skrypt nie „ t zmarł, a inny proces został uruchomiony przy użyciu tego samego PID) i sprawdzanie, czy skrypt faktycznie odpowiedział (zakończył) na pierwsze żądanie „zabicia”. Wykonanie wszystkich tych kontroli może się skomplikować i nie chciałem, aby przykład był zbyt długi i skomplikowany. Możesz zmodyfikować przykład, aby ćwiczyć skrypty powłoki.
Zapisz następujący kod w pliku o nazwie „programctl”, aby był wykonywalny za pomocą polecenia:
chmod 755 programctl
Następnie edytuj plik i dodaj swój kod / skrypt w sekcji przypadku zaczynającej się od „myscript”.
Gdy wszystko będzie już na swoim miejscu, zakładając, że „programctl” znajduje się w bieżącym katalogu, możesz uruchomić swój program za pomocą:
./programctl start
I przestań:
./programctl stop
Twoje zdrowie.
źródło