Aqui está outra maneira de bloquear o shell script que pode evitar a condição de corrida descrita acima, onde duas tarefas podem passar a linha 3. A opção noclobber
funcionará em ksh e bash. Não use set noclobber
porque você não deveria estar fazendo script no csh / tcsh. ;)
lockfile=/var/tmp/mylock
if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# do stuff here
# clean up after yourself, and release your trap
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Lock Exists: $lockfile owned by $(cat $lockfile)"
fi
YMMV com bloqueio no NFS (você sabe, quando os servidores NFS não estão acessíveis), mas em geral é muito mais robusto do que costumava ser. (Há 10 anos)
Se você tiver tarefas agendadas que façam a mesma coisa ao mesmo tempo, a partir de vários servidores, mas precisar de apenas uma instância para ser executada, algo assim poderá funcionar para você.
Eu não tenho experiência com o lockrun, mas ter um ambiente de bloqueio pré-definido antes de o script realmente ser executado pode ajudar. Ou talvez não. Você está apenas definindo o teste para o lockfile fora de seu script em um wrapper e, teoricamente, você não poderia simplesmente atingir a mesma condição de corrida se dois jobs fossem chamados por lockrun exatamente ao mesmo tempo, assim como com o 'inside- a solução do script?
O bloqueio de arquivos é praticamente digno do comportamento do sistema de honra, e qualquer script que não verificar a existência do arquivo de bloqueio antes da execução fará o que for necessário. Apenas colocando o teste lockfile e o comportamento adequado, você estará resolvendo 99% dos possíveis problemas, se não 100%.
Se você se deparar com as condições de corrida do arquivo lockfile, pode ser um indicador de um problema maior, como não ter seus trabalhos cronometrados corretamente ou talvez se o intervalo não for tão importante quanto o término do trabalho, talvez seu trabalho seja mais adequado para ser daemonized.
EDIT ABAIXO - 2016-05-06 (se você estiver usando o KSH88)
Baseie no comentário de @Clint Pachl abaixo, se você usar ksh88, use mkdir
em vez de noclobber
. Isso atenua principalmente uma possível condição de corrida, mas não a limita inteiramente (embora o risco seja minúsculo). Para mais informações, leia o link que o Clint postou abaixo .
lockdir=/var/tmp/mylock
pidfile=/var/tmp/mylock/pid
if ( mkdir ${lockdir} ) 2> /dev/null; then
echo $$ > $pidfile
trap 'rm -rf "$lockdir"; exit $?' INT TERM EXIT
# do stuff here
# clean up after yourself, and release your trap
rm -rf "$lockdir"
trap - INT TERM EXIT
else
echo "Lock Exists: $lockdir owned by $(cat $pidfile)"
fi
E, como uma vantagem, se você precisar criar tmpfiles no seu script, você pode usar o diretório lockdir
para eles, sabendo que eles serão limpos quando o script sair.
Para um bash mais moderno, o método noclobber no topo deve ser adequado.