crontab에서 스크립트 또는 응용 프로그램을 실행하고 두 번 실행되지 않도록하는 간단하고 일반적인 솔루션을 찾고 있습니다.
솔루션은 실행 된 명령과 독립적이어야합니다.
lock && (command ; unlock)
다른 잠금이 있으면 잠금이 false를 반환하는 위치 와 같아야한다고 가정합니다 .
두 번째 부분은 오류를 반환하더라도 잠금, 실행 명령 및 명령 실행 후 잠금 해제를 얻은 경우와 같습니다.
답변
상기 봐 가지고 실행 하나의run-one
명령
run-one 은 고유 한 인수 세트를 사용하여 명령의 고유 인스턴스를 하나 이상 실행하는 랩퍼 스크립트입니다.
한 번에 하나 이상의 사본을 실행하지 않으려는 경우 cronjob에 유용합니다.
time
또는 과 같이 sudo
명령 앞에 추가하면됩니다. 따라서 cronjob은 다음과 같습니다.
*/60 * * * * run-one rsync -azP $HOME example.com:/srv/backup
자세한 내용과 배경 은 Dustin Kirkland가 소개 한 블로그 게시물을 확인하십시오 .
답변
잠금을 설정하는 매우 간단한 방법 :
if mkdir /var/lock/mylock; then
echo "Locking succeeded" >&2
else
echo "Lock failed - exit" >&2
exit 1
fi
실행하려는 스크립트는 잠금을 생성해야합니다. 잠금이 존재하면 다른 스크립트가 사용 중이므로 첫 번째 스크립트를 실행할 수 없습니다. 파일이 존재하지 않으면 스크립트가 잠금을 획득하지 않은 것입니다. 따라서 현재 스크립트는 잠금을 획득합니다. 스크립트가 완료되면 잠금을 제거하여 잠금을 구현해야합니다.
bash 잠금에 대한 자세한 내용은 이 페이지를 확인 하십시오.
답변
멋진 패키지를 설치할 필요가 없습니다.
#!/bin/bash
pgrep -xf "$*" > /dev/null || "$@"
“apt-get install”을 실행하는 것보다 스크립트를 직접 작성하는 것이 더 빠르지 않습니까? 현재 사용자 만 실행하는 인스턴스를 확인하기 위해 “-u $ (id -u)”를 pgrep에 추가 할 수 있습니다.
답변
solo
사용자에게 고유 한 루프백 주소의 포트를 바인딩하여 잠금을 수행하는 Tim Kay ‘s도 참조하십시오 .
그의 사이트가 다운되는 경우 :
용법:
solo -port=PORT COMMAND
where
PORT some arbitrary port number to be used for locking
COMMAND shell command to run
options
-verbose be verbose
-silent be silent
다음과 같이 사용하십시오.
* * * * * solo -port=3801 ./job.pl blah blah
스크립트:
#!/usr/bin/perl -s
#
# solo v1.7
# Prevents multiple cron instances from running simultaneously.
#
# Copyright 2007-2016 Timothy Kay
# http://timkay.com/solo/
#
# It is free software; you can redistribute it and/or modify it under the terms of either:
#
# a) the GNU General Public License as published by the Free Software Foundation;
# either version 1 (http://dev.perl.org/licenses/gpl1.html), or (at your option)
# any later version (http://www.fsf.org/licenses/licenses.html#GNUGPL), or
#
# b) the "Artistic License" (http://dev.perl.org/licenses/artistic.html), or
#
# c) the MIT License (http://opensource.org/licenses/MIT)
#
use Socket;
alarm $timeout if $timeout;
$port =~ /^\d+$/ or $noport or die "Usage: $0 -port=PORT COMMAND\n";
if ($port)
{
# To work with OpenBSD: change to
# $addr = pack(CnC, 127, 0, 1);
# but make sure to use different ports across different users.
# (Thanks to www.gotati.com .)
$addr = pack(CnC, 127, $<, 1);
print "solo: bind ", join(".", unpack(C4, $addr)), ":$port\n" if $verbose;
$^F = 10; # unset close-on-exec
socket(SOLO, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "socket: $!";
bind(SOLO, sockaddr_in($port, $addr)) or $silent? exit: die "solo($port): $!\n";
}
sleep $sleep if $sleep;
exec @ARGV;
답변
자물쇠가 필요합니다. run-one
작업을 수행하지만 패키지 flock
에서 살펴볼 수도 있습니다 util-linux
.
커널 개발자가 제공하는 표준 패키지로, 더 많은 사용자 정의를 허용하며 run-one
여전히 매우 간단합니다.
답변
나를 위해 일한 bash-hackers.org 의 간단한 솔루션은 mkdir 을 사용하는 것 입니다. 이것은 하나의 프로그램 인스턴스 만 실행되도록하는 쉬운 방법입니다. 있는 디렉토리 만들기 에서 mkdir .lock 하는 수익을
- 성공적으로 만든 경우 true
- 잠금 파일이 존재하면 현재 실행중인 인스턴스가 하나 있음을 나타내는 false 입니다.
따라서이 간단한 함수는 모든 파일 잠금 논리를 수행했습니다.
if mkdir .lock; then
echo "Locking succeeded"
eval startYourProgram.sh ;
else
echo "Lock file exists. Program already running? Exit. "
exit 1
fi
echo "Program finished, Removing lock."
rm -r .lock
답변
이 솔루션은 자체 확인이 필요한 bash 스크립트를위한 것입니다.
v=$(pgrep -xf "/bin/bash $0 $@")
[ "${v/$BASHPID/}" != "" ] && exit 0