2011-01-22 22 views
12

Powiel możliwe:
Quick-and-dirty way to ensure only one instance of a shell script is running at a timeShell scenariusz: Upewnij się, że skrypt nie jest wykonywany, jeśli już działa

mam założyć cronjob do tworzenia kopii zapasowych moich foldery prawidłowo której jestem dość dumny z. Jednak, patrząc na wyniki z kopii zapasowych, dowiedziałem się, że mój skrypt zapasowy był wywoływany więcej niż raz przez Crontab, co skutkowało uruchomieniem wielu kopii zapasowych w tym samym czasie.

Czy jest jakiś sposób, że mogę zagwarantować, że określony skrypt powłoki nie zostanie uruchomiony, jeśli ten sam skrypt już jest wykonywany?

Dzięki

+0

Podobne pytanie: http://stackoverflow.com/questions/ 1440967/how-do-i-make-sure-my-bash-script-isnt-już-uruchomiony – mizo

+0

Patrz [Zarządzanie procesami] (http://mywiki.wooledge.org/ProcessManagement). –

Odpowiedz

33

Rozwiązaniem bez stanu wyścigu lub problemów z wcześniejszym wyjściem jest użycie pliku blokady. Narzędzie flock obsługuje to bardzo dobrze i może być używany tak:

flock -n /var/run/your.lockfile -c /your/script 

będzie natychmiast wrócić z non 0 statusu, jeśli skrypt jest już uruchomiony.

0

Możesz użyć pliku tmp.
Nazwany to tmpCronBkp.a, tmpCronBkp.b, tmpCronBkp.c ... itp. Wydany z twojego skryptu backupu.

Utwórz go na początku skryptu i usunąć go na końcu ...

W jakiś czas sprawdzić, czy plik istnieje, czy nie i co plik istnieje.

Czy próbowałeś już w ten sposób?

+0

Nie jestem pewien, czy całkowicie się wyjaśniłem, ale chcę się upewnić, że mój skrypt powłoki nie zostanie ponownie uruchomiony, jeśli jest już wywołany przez CRON i aktywny – Industrial

+0

Niech ten plik będzie zawierał PID rozpoczętego procesu. Więc będziesz w stanie dowiedzieć się, czy działa w ogóle. – akond

+0

tak, możesz sprawdzić plik tmp i wyjść z programu scrit, jeśli plik istnieje! – elp

7

Zwykła i prosty sposób, aby to zrobić, aby umieścić coś takiego:

if [[ -f /tmp/myscript.running ]] ; then 
    exit 
fi 
touch /tmp/myscript.running 

na górze ciebie scenariusza i

rm -f /tmp/myscript.running 

na końcu, aw trap funkcji w przypadku nie dociera do końca.

To nadal ma kilka potencjalnych problemów (takich jak stan wyścigu na górze), ale zrobi to w ogromnej większości przypadków.

+0

to zapobiegnie uruchomieniu skryptu, jeśli był wcześniej uruchamiany. – unbeli

+0

@unbeli: nie, nie będzie, ponieważ usuniesz plik wartownika przy wyjściu. – paxdiablo

+9

Istnieje warunek wyścigu z powodu TOCTOU (czas sprawdzenia, czas użycia) pomiędzy "plik nie istnieje" i "utwórz plik". Mechanizmem atomowym jest 'mkdir /tmp/myscript.running 2>/dev/null'. Jeśli katalog istnieje, 'mkdir' zakończy się niepowodzeniem, a jądro gwarantuje, że tylko jedno z uruchomionych jednocześnie poleceń' mkdir' (wywołania systemowe) się powiedzie. –

5

Dobrym sposobem bez pliku blokady:

ps | grep $0 | grep -v grep > /var/tmp/$0.pid 
pids=$(cat /var/tmp/$0.pid | cut -d ' ' -f 1) 
for pid in $pids 
do 
    if [ $pid -ne $$ ]; then 
     logprint " $0 is already running. Exiting" 
     exit 7 
    fi 
done 
rm -f /var/tmp/$0.pid 

to robi to bez pliku blokady, która jest cool. ps do pliku tymczasowego, zeskanuj pierwsze pole (pid #) i poszukaj siebie. Jeśli znajdziemy inną, to ktoś już działa. Grep $ 0 ma na celu skrócenie listy tylko do tych wystąpień tego programu, a grep -v grep pozbywa się linii będącej grepem :)

+1

Łatwiej jest użyć pgrep: 'pids = $ (pgrep 0); dla pid w $ pids' – Jeremy

Powiązane problemy