# [inicio] ejecutar script antes que crontab (solucionado)

## pcmaster

Hola,

Necesitaría que, cuando se inicia el sistema, se ejecutase un script.

En un principio, podría ponerlo en /etc/init.d/local.start, pero... sería imprescindible que el script se ejecutase siempre ANTES de que se lance la primera ejecución del crontab (en el crontab se ejecuta una orden cada minuto, y este script al inicio debería ejecutarse antes de la primera ejecución de la orden del crontab).

¿Ideas?

----------

## Inodoro_Pereyra

Bueno, si editas /etc/init.d/local vas a ver un par de líneas relevantes:

```
depend() {

        after *

}

```

Esta línea es la que obliga a local a no iniciarse a menos que se cumplan todas las dependencias, osea, todos los servicios de todos los runlevels anteriores tienen que estar corriendo previamente.

Podrías hacer una copia de /etc/init.d/local a /etc/init.d/ejemplo y modificar las dependencias para que se inicie antes de tiempo y agregarlo al runlevel que necesites. Por ejemplo en /etc/init.d/xdm:

```
depend() {

        need localmount

        # this should start as early as possible

        # we can't do 'before *' as that breaks it

        # (#139824) Start after ypbind and autofs for network authentication

        # (#145219) Could use lirc mouse as input device

        # (#70689 comment #92) Start after consolefont to avoid display corruption

        after bootmisc readahead-list ypbind autofs openvpn gpm netmount lircd consolefont

        before alsasound

        # Start before X

        use acpid consolekit hald xfs

}

```

Creo que se explica sola la sintaxis, no?

Volviendo a /etc/init.d/local se podría llamar directamente el script en cuestion, o hacer una copia de /etc/conf.d/local.start y local.stop a ejemplo.start y ejemplo.stop para poder iniciar y luego detener el servicio en cuestión modificandon en /etc/init.d/local la línea que lee el contenido de los dos archivos anteriores:

```
start() {

        ebegin "Starting local"

        # Add any misc programs that should be started

        # to /etc/conf.d/local.start

        if [[ -e /etc/conf.d/local.start ]] ; then

                source /etc/conf.d/local.start

        fi

        eend $? "Failed to start local"

}

stop() {

        ebegin "Stopping local"

        # Add any misc programs that should be stopped

        # to /etc/conf.d/local.stop

        if [[ -e /etc/conf.d/local.stop ]] ; then

                source /etc/conf.d/local.stop

        fi

        eend $? "Failed to stop local"

}

```

Salud!

----------

## pcmaster

Bueno, al final lo he solucionado. Ha resultado más fácil de lo que parecía.

La solución de cambiar el orden de arranque de /etc/init.d/local.start no era adecuada, porque ejecuta un orden que debe ejecutarse al final del iniico del sistema. La solución ha sido otra:

He convertido el script en un archivo que he puesto en /etc/init.d, y después lo he puesto para que se ejecute al iniciar el pc con un rc-update add

Al principio lo puse en el runlevel boot, ya que vixie-cron está en el default, y funciona, pero ntp-client está también en el runlevel default, y me interesaba que el script se ejecutara después que ntp-client, ya que toma la hora, y quiero que la tome después de ajustarla.

La solución, lo he puesto en el runlevel default, indicandole el depend adecuado.

El objetivo era llevar un control de los apagones eléctricos, controlando cuándo se desconecta el PC. Obviamente no podía poner nada en /etc/conf.d/local.stop porque estoy seguro que si se apaga el PC a saco por un apagón no se ejecuta  :Wink: 

Así que el archivo /etc/init.d/inicios ha quedado así:

#!/sbin/runscript

# Copyright 1999-2007 Gentoo Foundation

# Distributed under the terms of the GNU General Public License v2

# $Header: $

depend() {

        before cron

        after ntpd ntp-client

}

start() {

        ebegin "Iniciando log de  inicio"

        mkdir -p /var/log/inicios

        if (`test -f "/var/log/inicios/actual.log"`); then

                mv /var/log/inicios/actual.log /var/log/inicios/$"`date +%Y.%m.%d-%H:%M:%S`"

        fi

        eend $? "No se pudo iniciar el log de inicio"

}

Después he creado un archivo en /usr/local/sbin/inicios.sh que contiene:

#! /bin/bash

#

# Programa para comprobar los inicios del PC

echo `date +%Y.%m.%d-%H:%M:%S` >/var/log/inicios/actual.log

Y finalmente he añadido en el crontab la línea:

* * * * * /usr/local/sbin/inicios.sh

El funcionamiento es el siguiente: cada minuto, el script ejecutado por el crontab guarda la fecha y hora actual en un archivo /var/log/inicios/actual.log. Cuando arranca de nuevo tras un apagado (correcto o tras un corte), el archivo /etc/init.d/inicios se ejecuta y cambia el nombre del archivo poniéndole como nombre la hora y fecha actual. Por razones obvias debe ejecutarse antes de que lo haga el crontab por primera vez. El resultado es que en /var/log/inicios tenemos una serie de archivos cuyo nombre es la fecha y hora a la que se ha iniciado el PC, y cuyo contenido, de texto, es la hora a la que se había apagado antes de iniciar. Es decir, cada archivo contiene información sobre un período de tiempo durante el cual el PC ha permanecido apagado.

Ya sé que la solución de poner archivos manualmente por todo el disco no es muy elegante. A ver si me pongo a ello y hago un ebuild  :Wink: 

----------

## ekz

Guau.. definitivamente hoy mismo comienzo a aprender bash scripting.. buen uso le has dado.

SAludos

----------

## pcmaster

Jeje

Tengo otro script que controla el router cada minuto, y me permite saber si ha habido un corte de adsl, pero si el corte es de suministro eléctrico, no me permite saber la duración, sino solamente que ha cambiado la IP. Por eso he hecho éste.

Al principio no tenía muy claro cómo hacerlo, para que se ejecutase en el momento preciso, pero al final "se me encendió la lucecita" y ya está listo.

Si se os ocurre alguna mejora...

----------

## ekz

Hola, podrías agregar tu script que controla al router?

Es que un 5-10% de las veces falla la conección a internet al momento de conectarse al inicio del sistema, entonces quería agregar un script al inicio con un IF que verifique si hay conección. (Aunque no haga eso, me serviría de base)

Gracias de antemano

SAludos

----------

## pcmaster

Es más compliadillo que eso...

Lo que hace mi script es comprobar cada minuto el router, y si ha cambiado el estado (conectado, desconectado, etc) añade una línea a un archivo de registro. Evidentemente, hay que adaptarlo a cada modelo de router, aunque es fácil.  :Wink: 

Lo pondré en un hilo aparte cuando haya pulido un par de detallitos.

En cuanto a tu problema, entiendo que tu router está siempre conectado y al iniciar el sistema la conexión no está disponible hasta pasados unos minutos. ¿es así? Detalla más tu problema y miraremos de solucionarlo.

----------

## ekz

 :Very Happy:  !!

Al fin lo logré, mi primer script de bash, jeje.. admito que está MUY desordenado (y cutre), pero lo hice 100% yo y me gustó  :Smile: 

Verifica si hay conección a internet mediante un ping a google

```

#!/bin/sh

ping -c 1 www.google.cl 1> ~/pingcount

#guarda la salida estandar

#si hay errores, esta estara vacia

CADENA=$(cat ~/pingcount)

#echo "Variable CADENA contiene: $CADENA"

if test -z "$CADENA"

then 

  echo "la cadena esta vacia, hace verdadera la condicion, hay errores y no hay internet"

else

  echo "si hay internet la cadena contiene el ping, haciendo falsa la condicion, osea que hay internet"

fi

```

Explicación:

```
ping -c 1 www.google.cl 1> ~/pingcount
```

Crea/remplaza el fichero pingcount (le agregas un punto al inicio para que sea oculto) con la "salida estándar"(1) de un ping, si no hay internet, el ping devolverá un error, pero no mediante la salida estándar , sino mediante la "salida de errores"(2) 

```
CADENA=$(cat ~/pingcount)
```

Le asigna el contenido del fichero a la variable CADENA

```
if test -z "$CADENA"
```

test -z analiza la variable CADENA, y devuelve "Verdadero si la cadena esta vacía (su longitud es cero)"

```
then 

  echo "la cadena esta vacia, hace verdadera la condicion, hay errores y no hay internet"
```

Si no hay internet -> no hay ping -> el fichero no contiene datos -> la variable está vacía -> test -z devuelve 'Verdadero'

```
else

  echo "si hay internet la cadena contiene el ping, haciendo falsa la condicion, osea que hay internet"
```

Si hay internet -> hay ping -> el fichero contiene datos -> la variable contiene datos -> test -z  devuelve 'Falso' 

Que utilidad tiene?

los echo "texto" se pueden cambiar por  $(comando) , por lo cual puedes ejecutar 2 cosas distintas dependiendo si hay internet o no  :Smile: 

SAludos

----------

## Inodoro_Pereyra

Interesante... Se me vienen a la cabeza varias aplicaciones para un script así.

De hecho estaba esperando a que el amigo pcmaster publique el suyo...

Gracias por compartir.

Salud! (Este hilo va a parar a favoritos para tenerlo a mano)

----------

## pcmaster

Aquí tenéis el script:

https://forums.gentoo.org/viewtopic-p-4173131.html#4173131

----------

