Czy jest jakiś sposób, aby powiedzieć cronowi, aby uruchomił aplikację, ALE nie uruchamiać jej, jeśli proces już istnieje?
Czy jest jakiś sposób, aby powiedzieć cronowi, aby uruchomił aplikację, ALE nie uruchamiać jej, jeśli proces już istnieje?
Odpowiedzi:
najprostszym sposobem jest użycie pgrep
w crontab:
* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1
export DISPLAY=:0
aby uniknąć Could not connect to display
błędów. * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
Uruchom skrypt zamiast bezpośrednio programu. Istnieje wiele możliwości. Na przykład :
MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
$RESTART
fi
pgrep myprog; if [ $? -ne 0 ]; then ...
lepiej byłoby napisać jakoif ! pgrep myprog; then ...
$?
, na przykład poprzez dodanie komunikatów dziennika lub obsługę błędów między wierszami.
Ten skrypt nie uruchomi się ponownie, jeśli poprzednie wystąpienie się nie zakończyło. Jeśli nie chcesz coś uruchamiać, jeśli uruchomiony jest inny określony proces, zapoznaj się ze skryptem harrymca.
DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;
if flock -n -x 8; then
echo ""
echo "Starting your script..."
echo ""
[PUT YOUR STUFF HERE]
echo ""
echo "Script started $DATE";
echo "Script finished `date +%c`";
else
echo "Script NOT started - previous one still running at $DATE";
fi
Możesz użyć pliku blokady w swoim skrypcie, ale zobacz Zarządzanie procesami .
flock
to jedno narzędzie, którego można użyć.
*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
Zwykle jest to obsługiwane przez sam program, a nie przez cron
. Istnieją dwie standardowe techniki:
1) grep
wyjście, ps
aby sprawdzić, czy proces o tej nazwie już działa
2) Podczas uruchamiania najpierw sprawdź, czy plik pid (identyfikator procesu) jest zwykle w /var/run/program_name.pid
, a jeśli tak, przeczytaj pid z pliku i sprawdź, czy proces ten nadal istnieje; jeśli tak, odmów startu. Jeśli plik pid nie istnieje lub pid w pliku zniknął, utwórz plik pid, napisz do niego swój identyfikator procesu i kontynuuj normalne uruchamianie.
Chociaż technicznie możliwe jest pisanie rur bash, które wykonają jedno z tych bezpośrednio w twoim crontabie, lepiej jest dodać je do uruchamianego programu (tak, aby były stosowane bez względu na to, jak się uruchomi) lub napisać skrypt otoki radzimy sobie z tym, jak sugerował harrymc.
* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1
Ponownie wykorzystałem powyższą odpowiedź z poprawą dopasowania wzorca. pgrep bez opcji f nie pasuje do wzorca procesu. Istnieje jednak problem z użyciem opcji f. W opcji f powłoka odradzająca crona jest zawsze dopasowywana i zwraca swój pid, dlatego proces nigdy się nie restartuje.
Dodanie [] wokół wzorca jednej litery pasuje tylko do procesu, a pid powłoki cron nie jest zwracany.
Dokumenty: https://www.timkay.com/solo/
solo to bardzo prosty skrypt (10 linii), który zapobiega uruchamianiu przez program więcej niż jednej kopii na raz. Przydaje się w przypadku crona, aby upewnić się, że zadanie nie uruchomi się przed zakończeniem poprzedniego.
Przykład
* * * * * solo -port=3801 ./job.pl blah blah