Jak daemonizować dowolny skrypt w Uniksie?
Chciałbym daemonizera, który potrafi zamienić dowolny, ogólny skrypt lub polecenie w daemon .
Są dwa typowe przypadki, którymi chciałbym się zająć:
Mam skrypt, który powinien działać w nieskończoność. Jeśli kiedykolwiek umrze (lub po ponownym uruchomieniu), uruchom go ponownie. Nie pozwól, aby kiedykolwiek działały dwie kopie jednocześnie(Wykryj, czy kopia jest już uruchomiona i nie uruchamiaj jej w takim przypadku).
Mam prosty skrypt lub polecenie linii poleceń, które chciałbym zachować wykonywanie wielokrotnie w nieskończoność(z krótką przerwą między uruchomieniami). Ponownie, nie pozwól, aby dwie kopie skryptu kiedykolwiek były uruchomione na raz.
Oczywiście trywialne jest napisanie pętli "while(true)" wokół skryptu w przypadku 2, a następnie zastosowanie rozwiązania dla Przypadku 1, ale bardziej ogólne rozwiązanie po prostu rozwiąże przypadek 2 bezpośrednio, ponieważ dotyczy to również skryptu w przypadku 1 (możesz chcieć krótszej lub żadnej pauzy, jeśli skrypt nie ma na celu kiedykolwiek umrzeć (oczywiście, jeśli skrypt nie ma na celu kiedykolwiek umrzeć). naprawdę does never die then the pause doesn ' t actually matter)).
Zauważ, że rozwiązanie nie powinno obejmować, powiedzmy, dodawania kodu blokującego pliki lub nagrywania PID do istniejących skryptów.
Dokładniej, chciałbym program "daemonize", który mogę uruchomić jak
% daemonize myscript arg1 arg2
Lub, na przykład,
% daemonize 'echo `date` >> /tmp/times.txt'
Który utrzymywałby rosnącą listę dat dołączanych do czasów.txt. (Zauważ, że jeśli argument(y) do demonizacji jest skryptem, który działa w nieskończoność jak w przypadku 1 powyżej, to daemonize nadal będzie działać prawidłowo, uruchamiając go ponownie, gdy będzie to konieczne.) Mógłbym wtedy umieścić polecenie jak wyżej w moim .Zaloguj się i / lub cron to co godzinę lub minutely (w zależności od tego, jak martwiłem się o to, że umiera niespodziewanie).
NB: skrypt daemonize będzie musiał zapamiętać ciąg poleceń, który jest demonizowany, tak aby Jeśli ten sam ciąg poleceń jest demonizowany ponownie, nie uruchamia drugiej kopii.
Ponadto rozwiązanie powinno idealnie działać zarówno na OS X, jak i Linuksie, ale rozwiązania dla jednego lub inne są mile widziane.
EDIT: w porządku, jeśli musisz wywołać go za pomocą sudo daemonize myscript myargs
.
(jeśli myślę o tym źle lub są szybkie i brudne częściowe rozwiązania, też chciałbym to usłyszeć.)
PS: jeśli jest to przydatne, oto podobne pytanie specyficzne dla Pythona.
12 answers
Możesz demonizować dowolny plik wykonywalny w Uniksie używając nohup i operatora&:
nohup yourScript.sh script args&
Polecenie nohup pozwala na zamknięcie sesji powłoki bez zabijania skryptu, podczas gdy & umieszcza skrypt w tle, aby uzyskać monit powłoki, aby kontynuować sesję. Jedynym drobnym problemem jest standardowe wyjście i standardowy błąd, do którego są wysyłane.nohup.out, więc jeśli uruchomisz kilka skryptów w tym dworku ich wynik będzie spleciony. Lepsze dowodzenie be:
nohup yourScript.sh script args >script.out 2>script.error&
Spowoduje to wysłanie standardowego pliku do wybranego przez Ciebie pliku, a standardowego błędu do innego wybranego przez Ciebie pliku. Jeśli chcesz użyć tylko jednego pliku zarówno dla standardowego wyjścia, jak i standardowego błędu, możesz nam to zrobić:
nohup yourScript.sh script args >script.out 2>&1 &
2>&1 mówi powłoce, aby przekierowała błąd standardowy (deskryptor pliku 2) do tego samego pliku co standardowy out (deskryptor pliku 1).
Aby uruchomić polecenie tylko raz i zrestartować je, jeśli umrze, możesz użyć tego skryptu:
#!/bin/bash
if [[ $# < 1 ]]; then
echo "Name of pid file not given."
exit
fi
# Get the pid file's name.
PIDFILE=$1
shift
if [[ $# < 1 ]]; then
echo "No command given."
exit
fi
echo "Checking pid in file $PIDFILE."
#Check to see if process running.
PID=$(cat $PIDFILE 2>/dev/null)
if [[ $? = 0 ]]; then
ps -p $PID >/dev/null 2>&1
if [[ $? = 0 ]]; then
echo "Command $1 already running."
exit
fi
fi
# Write our pid to file.
echo $$ >$PIDFILE
# Get command.
COMMAND=$1
shift
# Run command until we're killed.
while true; do
$COMMAND "$@"
sleep 10 # if command dies immediately, don't go into un-ctrl-c-able loop
done
Pierwszy argument to nazwa używanego pliku pid. Drugim argumentem jest komenda. A wszystkie inne argumenty są argumentami komendy.
Jeśli nazwiesz ten skrypt restart.sh tak byś to nazwał:
nohup restart.sh pidFileName yourScript.sh script args >script.out 2>&1 &
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-02 15:53:54
Przepraszam za długą odpowiedź (proszę zapoznać się z komentarzami na temat tego, jak moja odpowiedź spełnia wymagania). Staram się być kompleksowy, żebyś miał jak najwięcej siły. :-)
Jeśli jesteś w stanie instalować programy (masz dostęp do roota) i jesteś gotów wykonać jednorazową pracę, aby skonfigurować skrypt do wykonywania demona (tj. bardziej zaangażowany niż po prostu określanie argumentów wiersza poleceń, które mają być uruchomione w wierszu poleceń, ale muszą być wykonane tylko raz na usługę), mam sposób, który może być bardziej wytrzymałe.
Polega na użyciu daemontools . Reszta posta opisuje jak skonfigurować usługi za pomocą daemontools.
Wstępna konfiguracja
-
Wykonaj instrukcje w Jak zainstalować daemontools . Niektóre dystrybucje (np. Debian, Ubuntu) mają już pakiety dla niego, więc po prostu użyj tego.
- Stwórz katalog o nazwie
/service
. Instalator powinien już to zrobić, ale wystarczy zweryfikować lub zainstalować ręcznie. Jeśli ci się to nie podoba lokalizacja, możesz ją zmienić w skrypciesvscanboot
, chociaż większość użytkowników daemontools jest przyzwyczajona do używania/service
i będzie zdezorientowana, jeśli jej nie użyjesz. - jeśli używasz Ubuntu lub innej dystrybucji, która nie używa standardowego
init
(tzn. nie używa/etc/inittab
), będziesz musiał użyć preinstalowanegoinittab
jako podstawy do organizowaniasvscanboot
do wywołania przezinit
. Nie jest to trudne, ale musisz wiedzieć, jak skonfigurowaćinit
, którego używa Twój system operacyjny.svscanboot
jest skryptem wywołującymsvscan
, który wykonuje główne praca szukania usług; nazywa się to odinit
, więcinit
zorganizuje ponowne uruchomienie go, jeśli umrze z jakiegokolwiek powodu.
Konfiguracja usługi
- każdy serwis potrzebuje katalog usług , który przechowuje informacje o serwisie. Możesz również zrobić lokalizację do przechowywania tych katalogów usług, aby wszystkie były w jednym miejscu; zwykle używam
/var/lib/svscan
, ale każda nowa lokalizacja będzie w porządku. -
Zwykle używam skryptu , aby skonfigurować katalog usług, aby zapisać wiele ręcznych powtarzalnych prac. np.,
sudo mkservice -d /var/lib/svscan/some-service-name -l -u user -L loguser "command line here"
Gdzie
some-service-name
jest nazwą, którą chcesz nadać swojej usłudze, {[16] } jest użytkownikiem, który uruchomi tę usługę, aloguser
jest użytkownikiem, który uruchomi logger jako. (Logowanie jest wyjaśnione tylko trochę.) - Twój serwis musi działać na pierwszym planie . Jeśli twój program domyślnie tła, ale ma opcję, aby wyłączyć, to zrobić. Jeśli twój program nie ma możliwości jego wyłączenia, Czytaj dalej
fghack
, chociaż jest to kompromis: nie można już kontrolować programu za pomocąsvc
. - Edytuj skrypt
run
, aby upewnić się, że robi to, co chcesz. Może być konieczne umieszczenie połączeniasleep
na górze, jeśli oczekujesz, że usługa będzie często opuszczana. - gdy wszystko jest dobrze skonfigurowane, Utwórz dowiązanie symboliczne w
/service
wskazujące na katalog usług. (Nie umieszczaj katalogów usług bezpośrednio w/service
; utrudnia to usunięcie usługi zsvscan
's watch.)
Logowanie
- sposób logowania daemontools polega na tym, aby usługa zapisywała komunikaty dziennika na standardowe wyjście (lub standardowy błąd, jeśli używasz skryptów wygenerowanych z
mkservice
);svscan
dba o wysyłanie wiadomości logowania do usługi logowania. - usługa logowania pobiera komunikaty dziennika ze standardowego wejścia. Skrypt usługi logowania wygenerowany przez
mkservice
utworzy automatycznie obracane pliki dziennika w katalogulog/main
. Prąd plik dziennika nazywa sięcurrent
. - usługa logowania może być uruchamiana i zatrzymywana niezależnie od usługi głównej.
- Przepuszczanie plików dziennika przez
tai64nlocal
przetłumaczy znaczniki czasu na format czytelny dla człowieka. (TAI64N to 64-bitowy Atomic timestamp z liczbą nanosekund.)
Controlling services
- użycie
svstat
aby uzyskać status usługi. Należy pamiętać, że usługa logowania jest niezależna i posiada własne status. - kontrolujesz swoją usługę (start, stop, restart itp.) za pomocą
svc
. Na przykład, aby ponownie uruchomić usługę, użyjsvc -t /service/some-service-name
;-t
oznacza " wyślijSIGTERM
". - inne dostępne sygnały obejmują
-h
(SIGHUP
),-a
(SIGALRM
),-1
(SIGUSR1
),-2
(SIGUSR2
), oraz-k
(SIGKILL
). - aby wyłączyć usługę, użyj
-d
. Można również zapobiec automatycznemu uruchomieniu usługi podczas rozruchu, tworząc plik o nazwiedown
w Katalogu usługi. - To uruchom usługę, użyj
-u
. Nie jest to konieczne, chyba że wcześniej go wyłączyłeś(lub Ustawiłeś, aby nie uruchamiał się automatycznie). - aby poprosić przełożonego o wyjście, użyj
-x
; zwykle używane z-d
również do zakończenia usługi. Jest to zwykły sposób, aby umożliwić usunięcie usługi, ale musisz najpierw odłączyć usługę od/service
, albosvscan
uruchomi ponownie nadzorcę. Ponadto, jeśli utworzyłeś swoją usługę za pomocą usługi logowania (mkservice -l
), pamiętaj, aby również zakończyć logowanie supervisor (np.svc -dx /var/lib/svscan/some-service-name/log
) przed usunięciem katalogu usług.
Podsumowanie
Plusy:
- daemontools zapewnia kuloodporny sposób tworzenia i zarządzania usługami. Używam go do moich serwerów i Gorąco polecam.
- jego system logowania jest bardzo solidny, podobnie jak funkcja automatycznego restartu serwisu.
- ponieważ uruchamia usługi ze skryptem powłoki, który piszesz/dostrajasz, możesz dostosować swoją usługę do własnych potrzeb.
- potężny serwis narzędzia sterowania: możesz wysłać większość dowolnego sygnału do usługi i niezawodnie wprowadzać usługi w górę iw dół.
- Twoje usługi mają zagwarantowane czyste środowisko wykonawcze: będą wykonywane z tym samym środowiskiem, ograniczeniami procesów itp., co zapewnia
init
.
Wady:
- każda usługa wymaga trochę konfiguracji. Na szczęście trzeba to zrobić tylko raz na usługę.
- usługi muszą być ustawione tak, aby działały na pierwszym planie. Również, aby uzyskać najlepsze wyniki, powinny być skonfigurowany do logowania do standardowego wyjścia / standardowego błędu, zamiast syslogu lub innych plików. [69]}stroma krzywa uczenia się, jeśli jesteś nowy w daemontools sposób robienia rzeczy. Trzeba zrestartować usługi używając
svc
i nie można bezpośrednio uruchomić skryptów run (ponieważ wtedy nie byłyby one pod kontrolą przełożonego).
Wiele plików porządkowych i wiele procesów porządkowych. Każda usługa potrzebuje własnego katalogu usług, a każda usługa wykorzystuje jeden proces nadzorcy do auto-restart usługi, jeśli umrze. (Jeśli masz wiele usług, zobaczysz wiele supervise
procesów w tabeli procesów.)
W równowadze, myślę, że daemontools jest doskonałym systemem dla Twoich potrzeb. Czekam na wszelkie pytania, jak je skonfigurować i utrzymać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-18 04:57:20
Powinieneś rzucić okiem na daemonize . Pozwala na wykrycie drugiej kopii (ale wykorzystuje mechanizm blokowania plików). Działa również na różnych dystrybucjach UNIX i Linux.
Jeśli chcesz automatycznie uruchomić aplikację jako demon, musisz utworzyć odpowiedni skrypt init.
Możesz użyć następującego szablonu:
#!/bin/sh
#
# mydaemon This shell script takes care of starting and stopping
# the <mydaemon>
#
# Source function library
. /etc/rc.d/init.d/functions
# Do preliminary checks here, if any
#### START of preliminary checks #########
##### END of preliminary checks #######
# Handle manual control parameters like start, stop, status, restart, etc.
case "$1" in
start)
# Start daemons.
echo -n $"Starting <mydaemon> daemon: "
echo
daemon <mydaemon>
echo
;;
stop)
# Stop daemons.
echo -n $"Shutting down <mydaemon>: "
killproc <mydaemon>
echo
# Do clean-up works here like removing pid files from /var/run, etc.
;;
status)
status <mydaemon>
;;
restart)
$0 stop
$0 start
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 1
esac
exit 0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-17 02:52:10
Myślę, że możesz chcieć spróbować start-stop-daemon(8)
. Sprawdź skrypty w /etc/init.d
W dowolnej dystrybucji Linuksa, aby znaleźć przykłady. Może znaleźć rozpoczęte procesy przez wywołany wiersz poleceń lub plik PID, więc spełnia wszystkie twoje wymagania, z wyjątkiem bycia watchdog dla Twojego skryptu. Ale zawsze można uruchomić inny skrypt DAEMON watchdog, który po prostu uruchamia ponownie skrypt, jeśli to konieczne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 01:25:44
Jako alternatywa dla wymienionych już daemonize
i daemontools
, istnieje polecenie daemon pakietu libslack.
daemon
jest dość konfigurowalny i dba o wszystkie żmudne rzeczy demona, takie jak automatyczne ponowne uruchamianie, rejestrowanie lub Obsługa plików PID.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-09 14:46:06
Jeśli używasz OS X konkretnie, proponuję rzucić okiem na działanie launchd. Automatycznie sprawdzi, czy skrypt jest uruchomiony i w razie potrzeby uruchom go ponownie. Zawiera również wszelkiego rodzaju funkcje planowania, itp. Powinien spełniać zarówno wymóg 1, jak i 2.
Aby zapewnić, że tylko jedna kopia skryptu może zostać uruchomiona, musisz użyć pliku PID. Generalnie zapisuję plik do /var / run/.pid, który zawiera PID bieżącej uruchomionej instancji. jeśli plik istnieje, gdy program działa, sprawdza, czy PID w pliku jest rzeczywiście uruchomiony (program mógł się zawiesić lub w inny sposób zapomniał usunąć plik PID). Jeśli tak, przerwij. Jeśli nie, zacznij działać i Nadpisz plik PID.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-08 08:33:25
Daemontools (http://cr.yp.to/daemontools.html ) jest zestawem dość hard-core narzędzia używane do tego, napisany przez dj bernstein. Użyłem tego z pewnym sukcesem. Irytujące jest to, że żaden ze skryptów nie zwraca widocznych wyników po ich uruchomieniu - po prostu niewidoczne kody zwrotne. Ale po uruchomieniu jest kuloodporny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-17 05:11:50
Najpierw pobierz createDaemon()
z http://code.activestate.com/recipes/278731/
Następnie główny kod:
import subprocess
import time
createDaemon()
while True:
subprocess.call(" ".join(sys.argv[1:]),shell=True)
time.sleep(10)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-08 15:37:41
Jest to wersja robocza wraz z przykładem, który możesz skopiować do pustego katalogu i wypróbować (po zainstalowaniu zależności CPAN, które są Getopt:: Long, plik: Spec, File:: Pid , and IPC:: System:: Simple -- all pretty standard and are highly recommended for any hacker: you can install them all at once with cpan <modulename> <modulename> ...
).
KeepAlive.pl:
#!/usr/bin/perl
# Usage:
# 1. put this in your crontab, to run every minute:
# keepAlive.pl --pidfile=<pidfile> --command=<executable> <arguments>
# 2. put this code somewhere near the beginning of your script,
# where $pidfile is the same value as used in the cron job above:
# use File::Pid;
# File::Pid->new({file => $pidfile})->write;
# if you want to stop your program from restarting, you must first disable the
# cron job, then manually stop your script. There is no need to clean up the
# pidfile; it will be cleaned up automatically when you next call
# keepAlive.pl.
use strict;
use warnings;
use Getopt::Long;
use File::Spec;
use File::Pid;
use IPC::System::Simple qw(system);
my ($pid_file, $command);
GetOptions("pidfile=s" => \$pid_file,
"command=s" => \$command)
or print "Usage: $0 --pidfile=<pidfile> --command=<executable> <arguments>\n", exit;
my @arguments = @ARGV;
# check if process is still running
my $pid_obj = File::Pid->new({file => $pid_file});
if ($pid_obj->running())
{
# process is still running; nothing to do!
exit 0;
}
# no? restart it
print "Pid " . $pid_obj->pid . " no longer running; restarting $command @arguments\n";
system($command, @arguments);
Example.pl:
#!/usr/bin/perl
use strict;
use warnings;
use File::Pid;
File::Pid->new({file => "pidfile"})->write;
print "$0 got arguments: @ARGV\n";
Teraz możesz wywołać powyższy przykład za pomocą: ./keepAlive.pl --pidfile=pidfile --command=./example.pl 1 2 3
, A Plik pidfile
zostanie utworzony i zobaczysz wyjście:
Pid <random number here> no longer running; restarting ./example.pl 1 2 3
./example.pl got arguments: 1 2 3
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-08 08:34:06
Możesz również spróbować Monit . Monit to usługa, która monitoruje i raportuje inne usługi. Chociaż jest używany głównie jako sposób powiadamiania (za pośrednictwem poczty e-mail i sms) o problemach związanych z uruchomieniem, może również zrobić to, co zalecało większość innych sugestii. Może automatycznie (ponownie)uruchamiać i zatrzymywać programy, wysyłać wiadomości e-mail, inicjować Inne skrypty i utrzymywać dziennik wyników, które możesz odebrać. Ponadto odkryłem, że jest łatwy w instalacji i utrzymaniu, ponieważ istnieje solidna dokumentacja.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 13:51:55
Możesz spróbować immortal jest to * Nix cross-platform (OS) supervisor.
Jeśli nie masz jeszcze konta na macOS]}brew install immortal
Jeśli używasz FreeBSD z portów lub używając pkg:
pkg install immortal
Dla Linuksa pobierając wstępnie skompilowane binaria lub ze źródła: https://immortal.run / source /
Możesz go użyć w następujący sposób:
immortal -l /var/log/date.log date
Lub przez plik konfiguracyjny YAML , który daje więcej opcje, na przykład:
cmd: date
log:
file: /var/log/date.log
age: 86400 # seconds
num: 7 # int
size: 1 # MegaBytes
timestamp: true # will add timesamp to log
Jeśli chcesz zachować również standardowe wyjście błędu w osobnym pliku, możesz użyć czegoś takiego jak:
cmd: date
log:
file: /var/log/date.log
age: 86400 # seconds
num: 7 # int
size: 1 # MegaBytes
stderr:
file: /var/log/date-error.log
age: 86400 # seconds
num: 7 # int
size: 1 # MegaBytes
timestamp: true # will add timesamp to log
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-07 19:07:14
Wprowadziłem szereg ulepszeń na inna odpowiedź.
- stdout z tego skryptu składa się wyłącznie ze stdout pochodzącego z jego potomka, chyba że zakończy się z powodu wykrycia, że komenda jest już uruchomiona
- czyści po zakończeniu pidfile
- opcjonalny konfigurowalny okres czasu (przyjmuje dowolny dodatni argument liczbowy, wysyła do
sleep
) - znak zachęty na
-h
- dowolne wykonywanie poleceń, a nie pojedyncze wykonanie polecenia. Ostatnie arg lub pozostałe args (jeśli więcej niż jedno ostatnie arg) są wysyłane do
eval
, więc można skonstruować dowolny skrypt powłoki jako ciąg znaków, aby wysłać do tego skryptu jako ostatnie arg (lub końcowe args), aby daemonize - porównywanie liczby argumentów za pomocą
-lt
zamiast<
Oto skrypt:
#!/bin/sh
# this script builds a mini-daemon, which isn't a real daemon because it
# should die when the owning terminal dies, but what makes it useful is
# that it will restart the command given to it when it completes, with a
# configurable timeout period elapsing before doing so.
if [ "$1" = '-h' ]; then
echo "timeout defaults to 1 sec.\nUsage: $(basename "$0") sentinel-pidfile [timeout] command [command arg [more command args...]]"
exit
fi
if [ $# -lt 2 ]; then
echo "No command given."
exit
fi
PIDFILE=$1
shift
TIMEOUT=1
if [[ $1 =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
TIMEOUT=$1
[ $# -lt 2 ] && echo "No command given (timeout was given)." && exit
shift
fi
echo "Checking pid in file ${PIDFILE}." >&2
#Check to see if process running.
if [ -f "$PIDFILE" ]; then
PID=$(< $PIDFILE)
if [ $? = 0 ]; then
ps -p $PID >/dev/null 2>&1
if [ $? = 0 ]; then
echo "This script is (probably) already running as PID ${PID}."
exit
fi
fi
fi
# Write our pid to file.
echo $$ >$PIDFILE
cleanup() {
rm $PIDFILE
}
trap cleanup EXIT
# Run command until we're killed.
while true; do
eval "$@"
echo "I am $$ and my child has exited; restart in ${TIMEOUT}s" >&2
sleep $TIMEOUT
done
Użycie:
$ term-daemonize.sh pidfilefortesting 0.5 'echo abcd | sed s/b/zzz/'
Checking pid in file pidfilefortesting.
azzzcd
I am 79281 and my child has exited; restart in 0.5s
azzzcd
I am 79281 and my child has exited; restart in 0.5s
azzzcd
I am 79281 and my child has exited; restart in 0.5s
^C
$ term-daemonize.sh pidfilefortesting 0.5 'echo abcd | sed s/b/zzz/' 2>/dev/null
azzzcd
azzzcd
azzzcd
^C
Uważaj, że jeśli uruchomisz ten skrypt z różnych katalogów, może on używać różnych plików PID i nie wykrywać wszystkie istniejące uruchomione instancje. Ponieważ jest on przeznaczony do uruchamiania i restartowania efemerycznych poleceń dostarczanych przez argument, nie ma sposobu, aby dowiedzieć się, czy coś zostało już uruchomione, bo kto ma powiedzieć, czy jest to ta sama Komenda czy nie? Aby usprawnić egzekwowanie stosowania tylko jednej instancji czegoś, wymagane jest rozwiązanie specyficzne dla danej sytuacji.
Również, aby działał jako właściwy Demon, musisz użyć (minimum) nohup jako drugiego odpowiedź wspomina. Dołożyłem wszelkich starań, aby zapewnić odporność na sygnały, które proces może otrzymać.
Należy jeszcze zwrócić uwagę na to, że zabicie tego skryptu (jeśli został wywołany z innego skryptu, który jest zabity, lub z sygnałem) może nie odnieść sukcesu w zabiciu dziecka, zwłaszcza jeśli dziecko jest kolejnym skryptem {32]}. Nie wiem, dlaczego tak jest, ale wydaje mi się, że jest to coś związanego ze sposobem działania eval
, który jest dla mnie tajemniczy. Więc może być rozsądne, aby zastąpić ta linia z czymś, co akceptuje tylko jedno polecenie, jak w drugiej odpowiedzi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:38