Discussion:
Problema script bash en cron
(demasiado antiguo para responder)
Seve
2010-04-05 07:05:16 UTC
Permalink
Hola

Necesito una ayudita :)

Queremos lanzar un script desde el cron en una Centos5. El script se
llama cada minuto y aunque habitualmente termina en cuestión de
segundos, hay veces que puede tardar varios minutos.

Como no nos interesa que el script se ejecute dos veces, hacemos un ps y
buscamos que no estuviera en ejecución. El problema que tenemos es que
cuando quiere da error porque el shell parece lanzarse dos veces y da un
"falso positivo".

Mosqueados, hemos hecho el sscript que pongo más abajo y lo hemos
colgado en el cron. Lo que hace es ver si está en el mismo nodo que en
el que corre apache (es un cluster). Si es el mismo, saca la lista de
procesos, busca su nombre, quita grep, se quita a sí mismo y si la lista
está vacía, supone que no está ya en ejecución y hace lo que tenga que
hacer (TEST_CRON.sh en este caso).

Entrada en cron:
* * * * * /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh # Test

Script:
------------------
#!/bin/bash
#
servicio="apache"
LOG=/usr/bin/hvs/cron/cron_loglocal.log

dondeestoy=`/usr/sbin/clustat | /bin/grep Local | /bin/awk '{print $1}'`
dondeesta=`/usr/sbin/clustat -s apache | /bin/grep "service:$servicio" |
/bin/awk '{print $2}'`

/bin/echo "["`date "+%Y%m%d %H:%M:%S"`"] -1 Inicia $0" >> $LOG

if [ "$dondeestoy" == "$dondeesta" ]
then
procesos=`/bin/ps -ef|/bin/grep $0|/bin/grep -v grep|/bin/grep -v $$`
/bin/echo "["`date "+%Y%m%d %H:%M:%S"`"] -2 Antes procesos
($procesos)... $0" >> $LOG
if [ "$procesos" == "" ]
then
/bin/echo "["`date "+%Y%m%d %H:%M:%S"`"] -3 Se ejecuta $0" >> $LOG
/bin/sh /mnt/cluster/apache/cron/migrado/TEST_CRON.sh
fi
fi

/bin/echo "["`date "+%Y%m%d %H:%M:%S"`"] -4 Finaliza $0" >> $LOG

------------------

Como creo que se va a descuadrar, está descargable aquí:
http://www.vicius.org/publico/scriptecol.tar

El problema lo tenemos en "procesos". Como digo, habitualmente se lanza así:
crond -> bash
Pero cuando quiere, que es cuando falla, el script se lanza así:
crond -> bash -> bash
Y no tenemos ni idea de por qué.

Este es el log cuando va bien:
[20100405 08:42:01] -1 Inicia /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh
[20100405 08:42:01] -2 Antes procesos ()...
/usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh
[20100405 08:42:01] -3 Se ejecuta /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh
[20100405 08:42:01] -4 Finaliza /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh

Este es cuando casca:
[20100405 08:40:01] -1 Inicia /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh
[20100405 08:40:02] -2 Antes procesos (root 31305 31296 0 08:40 ?
00:00:00 /bin/bash /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh)...
/usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh
[20100405 08:40:02] -4 Finaliza /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh

Permisos del fichero:
-rwxr-xr-x 1 root root 737 mar 30 21:21 TEST_CLUSTER.sh

La opción de usar un fichero bandera al estilo de los scripts de init.d
no creo que nos sirva porque el nodo se puede reiniciar "porque sí"
(stonith) y el ficherillo se podría quedar sin borrar, dejándonos el
"invento" parado.

¿Qué leches se nos escapa? Llevamos usando ese método años en otras
distribuciones más antiguas sin problemas. ¿Se os ocurre otra idea mejor
de saber si algo está en ejecución?

Gracias y un saludo.
--
Seve.
EChMotor#486 BPD#6 Linux user#134969
306 XT HDI 2000-... Caleidoscopio Free
Canon EOS 400D + BG-E3 - S 17-70 - S 55-200 - C 100-400L IS - Helios-44M
RMC TK 24 F2.8 - Dryzone 200 - Toploader 70 AW - Canon Speedlite 430EX
seve < @ > vicius < . > org
Las FAQ de es.comp.hardware.misc en http://www.escomphardwaremisc.org
Gonzalo Pérez de Olaguer Córdoba
2010-04-05 14:38:24 UTC
Permalink
Post by Seve
Hola
Necesito una ayudita :)
Añade la opción set -x al principio del script y prueba
de nuevo. Obtendrás más info.
--
Gonzalo Pérez de Olaguer Córdoba <***@iies.es> --- www.gpoc.es
PGP key 2861C704 --- F206 5671 6789 425D 111C 1302 214F 1934 2861 C704
Seve
2010-04-05 22:17:30 UTC
Permalink
Post by Gonzalo Pérez de Olaguer Córdoba
Post by Seve
Hola
Necesito una ayudita :)
Añade la opción set -x al principio del script y prueba
de nuevo. Obtendrás más info.
Ok, mañana probamos a ver qué sale, porque es curioso que unas veces
vaya y otras no y sobre todo que falle en las Centos 5 y no nos haya
fallado en las otras máquinas más antiguas.
--
Seve.
EChMotor#486 BPD#6 Linux user#134969
306 XT HDI 2000-... Caleidoscopio Free
Canon EOS 400D + BG-E3 - S 17-70 - S 55-200 - C 100-400L IS - Helios-44M
RMC TK 24 F2.8 - Dryzone 200 - Toploader 70 AW - Canon Speedlite 430EX
seve < @ > vicius < . > org
Las FAQ de es.comp.hardware.misc en http://www.escomphardwaremisc.org
Pascal J. Bourguignon
2010-04-05 18:11:00 UTC
Permalink
Post by Seve
Hola
Necesito una ayudita :)
Queremos lanzar un script desde el cron en una Centos5. El script se
llama cada minuto y aunque habitualmente termina en cuestión de
segundos, hay veces que puede tardar varios minutos.
Como no nos interesa que el script se ejecute dos veces, hacemos un ps
y buscamos que no estuviera en ejecución. El problema que tenemos es
que cuando quiere da error porque el shell parece lanzarse dos veces y
da un "falso positivo".
Mosqueados, hemos hecho el sscript que pongo más abajo y lo hemos
colgado en el cron. Lo que hace es ver si está en el mismo nodo que en
el que corre apache (es un cluster). Si es el mismo, saca la lista de
procesos, busca su nombre, quita grep, se quita a sí mismo y si la
lista está vacía, supone que no está ya en ejecución y hace lo que
tenga que hacer (TEST_CRON.sh en este caso).
Tenemos el problema general en unix para saber si un programa dado esta
ejecutandose. En linux, se puede usar lockf(1):

--------------------(test-cluster)-------------------------------------
#!/bin/bash
exc flock -x -n "/var/lock/test-cluster/pid.lock" -c test-cluster-do-it
-----------------------------------------------------------------------
--
__Pascal Bourguignon__
Seve
2010-04-05 22:16:32 UTC
Permalink
Post by Pascal J. Bourguignon
Post by Seve
Como no nos interesa que el script se ejecute dos veces, hacemos un ps
y buscamos que no estuviera en ejecución. El problema que tenemos es
que cuando quiere da error porque el shell parece lanzarse dos veces y
da un "falso positivo".
Tenemos el problema general en unix para saber si un programa dado esta
Ostras, no había caído en usar bloqueos sobre ficheros en lugar de
ficheros bandera. Una idea estupenda. Mañana probamos :D

Muchas gracias.
--
Seve.
EChMotor#486 BPD#6 Linux user#134969
306 XT HDI 2000-... Caleidoscopio Free
Canon EOS 400D + BG-E3 - S 17-70 - S 55-200 - C 100-400L IS - Helios-44M
RMC TK 24 F2.8 - Dryzone 200 - Toploader 70 AW - Canon Speedlite 430EX
seve < @ > vicius < . > org
Las FAQ de es.comp.hardware.misc en http://www.escomphardwaremisc.org
dx
2010-04-06 09:12:56 UTC
Permalink
Post by Pascal J. Bourguignon
[...]
exc flock -x -n "/var/lock/test-cluster/pid.lock" -c test-cluster-do-it
Vaya, no conocía sobre flock. Gracias.

dx
jose maria
2010-04-06 16:19:27 UTC
Permalink
Post by Seve
Hola
Necesito una ayudita :)
Queremos lanzar un script desde el cron en una Centos5. El script se
llama cada minuto y aunque habitualmente termina en cuestión de
segundos, hay veces que puede tardar varios minutos.
Como no nos interesa que el script se ejecute dos veces, hacemos un ps y
buscamos que no estuviera en ejecución. El problema que tenemos es que
cuando quiere da error porque el shell parece lanzarse dos veces y da un
"falso positivo".
Mosqueados, hemos hecho el sscript que pongo más abajo y lo hemos
colgado en el cron. Lo que hace es ver si está en el mismo nodo que en
el que corre apache (es un cluster). Si es el mismo, saca la lista de
procesos, busca su nombre, quita grep, se quita a sí mismo y si la lista
está vacía, supone que no está ya en ejecución y hace lo que tenga que
hacer (TEST_CRON.sh en este caso).
* * * * * /usr/bin/hvs/cron/migrados/TEST_CLUSTER.sh # Test
* Si tienes muchos y distintos, como es mi caso, en cron u otros front-ends,
los lanzo como argumento con el del enlace, invitado invitado para acceder,
me evita programarlo en los propios scripts, con la opcion de especificar un
usuario o pararlos de forma ordenada, independientemente del script.

https://doc.usernix.org:4443/index.php?module=fileview&objectId=7401
Loading...