Use o floco conforme descrito em Trabalhos sobrepostos - bloqueios .
Eu tenho um cron job que é executado a cada minuto, mas se encontrar dados, pode levar muitos minutos para ser concluído.
Preciso dizer se outra instância do script está sendo executada em outro. Para tornar as coisas ainda mais divertidas, chamamos o mesmo script, com parâmetros diferentes. Por exemplo:
* * * * * /home/user/script.sh Dir1 > /tmp/logdir1.log
* * * * * /home/user/script.sh Dir2 > /tmp/logdir2.log
Eu testei algo assim:
FORMAT="'basename $0' $1"
OLDPID='pgrep -f -o "${FORMAT}"' #grab the oldest copy of the PID matching this format
echo $OLDPID:$$
If [ "$OLDPID" -eq "$$" ]
....
No meu teste, isso funciona muito bem, se o PID mais antigo não for o mesmo que o atual, existe outro em execução. no entanto, ao executar a partir do cron, o processo aparece duas vezes e, portanto, o pid mais antigo NÃO é o atual:
user 1094 0.0 0.0 8720 944 ? Ss 12:38 0:00 \_ /bin/sh -c /home/user/script.sh Dir1 > /tmp/logdir1.log
user 1097 0.1 0.0 8856 1236 ? S 12:38 0:00 \_ /bin/bash /home/user/script.sh Dir1
Então, meu script falha, todas as vezes, porque ele vê uma duplicata. Existe uma maneira de dizer ao pgrep para ignorar o primeiro?
Tivemos alguns problemas no passado ao ler um pidfile e ver se esse processo ainda está sendo executado. (outros processos obtêm o mesmo pid e diferentes versões do centos parecem ter parâmetros PS ligeiramente diferentes)
Como você trabalharia com isso?
Use o floco conforme descrito em Trabalhos sobrepostos - bloqueios .
Faça algo assim:
#!/bin/bash
pidfile=/var/run/myscript.pid
if [ -f ${pidfile} ]; then # is there already a pid file?
oldpid=$(cat ${pidfile})
ps -p ${oldpid} &> /dev/null # is the process still running?
if [ $? -ne 0 ]; then
rm ${pidfile} # pid file is stale, remove it
else
echo "Old process still running"
exit 1
fi
fi
echo $$ > ${pidfile}
# DO STUFF
rm ${pidfile}