22 votos

Linux: Programación de comandos para ejecutar una vez después de reiniciar el sistema (Run equivalente)

Me gustaría programar un comando para que se ejecute después de reiniciar el sistema en un cuadro de Linux. Yo sé cómo hacer esto, por lo que el comando constantemente se ejecuta después de cada reinicio con un @reboot crontab entrada, sin embargo yo sólo quiero que el comando se ejecute una vez. Después de que se ejecuta, debe ser eliminado de la cola de comandos a ejecutar. Estoy esencialmente buscando un Linux equivalente a RunOnce en el mundo de Windows.

En caso de que lo que importa:

$ uname -a
Linux devbox 2.6.27.19-5-default #1 SMP 2009-02-28 04:40:21 +0100 x86_64 x86_64 x86_64 GNU/Linux
$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
$ cat /etc/SuSE-release
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 0

Hay una manera fácil de secuencias de comandos manera de hacer esto?

36voto

jason saldo Puntos 5036

Crear un @reboot entrada en el crontab para que se ejecute un script llamado /usr/local/bin/runonce.

Crear una estructura de directorio llamado /etc/local/runonce.d/ran uso de mkdir -p.

Crear el script /usr/local/bin/runonce como sigue:

#!/bin/sh
for file in /etc/local/runonce.d/*
do
    if [ ! -f "$file" ]
    then
        continue
    fi
    "$file"
    mv "$file" "/etc/local/runonce.d/ran/$file.$(date +%Y%m%dT%H%M%S)"
    logger -t runonce -p local3.info "$file"
done

Ahora coloque ninguna secuencia de comandos que desea ejecutar en el siguiente reinicio (sólo una vez) en el directorio /etc/local/runonce.d y chown y chmod +x de forma adecuada. Una vez que se ha ejecutado, usted encontrará que se trasladó a la ran subdirectorio y la fecha y la hora anexa a su nombre. También habrá una entrada en su syslog.

21voto

Christopher Parker Puntos 213

Realmente aprecio el esfuerzo que se puso en Dennis Williamson respuesta. Yo quería aceptarlo como la respuesta a esta pregunta, ya que es elegante y simple, sin embargo:

  • En última instancia, consideró que se requiere demasiados pasos para configurar.
  • Se requiere acceso de root.

Creo que su solución sería genial un out-of-the-box característica de una distribución de Linux.

Dicho esto, yo escribí mi propio script para realizar más o menos la misma cosa como Dennis solución. No requiere ninguna instalación adicional de pasos y no requiere acceso de root.

#!/bin/bash

if [[ $# -eq 0 ]]; then
    echo "Schedules a command to be run after the next reboot."
    echo "Usage: $(basename $0) <command>"
    echo "       $(basename $0) -p <path> <command>"
    echo "       $(basename $0) -r <command>"
else
    REMOVE=0
    COMMAND=${!#}
    SCRIPTPATH=$PATH

    while getopts ":r:p:" optionName; do
        case "$optionName" in
            r) REMOVE=1; COMMAND=$OPTARG;;
            p) SCRIPTPATH=$OPTARG;;
        esac
    done

    SCRIPT="${HOME}/.$(basename $0)_$(echo $COMMAND | sed 's/[^a-zA-Z0-9_]/_/g')"

    if [[ ! -f $SCRIPT ]]; then
        echo "PATH=$SCRIPTPATH" >> $SCRIPT
        echo "cd $(pwd)"        >> $SCRIPT
        echo "logger -t $(basename $0) -p local3.info \"COMMAND=$COMMAND ; USER=\$(whoami) ($(logname)) ; PWD=$(pwd) ; PATH=\$PATH\"" >> $SCRIPT
        echo "$COMMAND | logger -t $(basename $0) -p local3.info" >> $SCRIPT
        echo "$0 -r \"$(echo $COMMAND | sed 's/\"/\\\"/g')\""     >> $SCRIPT
        chmod +x $SCRIPT
    fi

    CRONTAB="${HOME}/.$(basename $0)_temp_crontab_$RANDOM"
    ENTRY="@reboot $SCRIPT"

    echo "$(crontab -l 2>/dev/null)" | grep -v "$ENTRY" | grep -v "^# DO NOT EDIT THIS FILE - edit the master and reinstall.$" | grep -v "^# ([^ ]* installed on [^)]*)$" | grep -v "^# (Cron version [^$]*\$[^$]*\$)$" > $CRONTAB

    if [[ $REMOVE -eq 0 ]]; then
        echo "$ENTRY" >> $CRONTAB
    fi

    crontab $CRONTAB
    rm $CRONTAB

    if [[ $REMOVE -ne 0 ]]; then
        rm $SCRIPT
    fi
fi

Guardar este archivo de comandos (por ejemplo,: runonce), chmod +x, y ejecutar:

$ runonce foo
$ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)"

En el caso de un error tipográfico, puede eliminar un comando de la runonce cola con el r-bandera:

$ runonce fop
$ runonce -r fop
$ runonce foo

El uso de sudo funciona de la manera que esperas que funcione. Útil para iniciar un servidor sólo una vez después del próximo reinicio.

myuser@myhost:/home/myuser$ sudo runonce foo
myuser@myhost:/home/myuser$ sudo crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/root/.runonce_temp_crontab_10478 installed on Wed Jun  9 16:56:00 2010)
# (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $)
@reboot /root/.runonce_foo
myuser@myhost:/home/myuser$ sudo cat /root/.runonce_foo
PATH=/usr/sbin:/bin:/usr/bin:/sbin
cd /home/myuser
foo
/home/myuser/bin/runonce -r "foo"

Algunas notas:

  • Esta secuencia de comandos se replica el medio ambiente (PATHde acceso de directorio de trabajo, el usuario) se invoca.
  • Está diseñado básicamente, de aplazar la ejecución de un comando como sería ejecutado "a la derecha aquí, ahora" hasta después de la siguiente secuencia de arranque.

4voto

mpez0 Puntos 1237

Configurar el script en /etc/rc5.d con un S99 y tiene que eliminar a sí mismo después de correr.

3voto

kaffeslangen Puntos 11

Crear por ejemplo /root/runonce.sh:

#!/bin/bash

#el comando aquí

sed-i '/runonce.sh/d' /etc/rc.local

Añadir a /etc/rc.local:

/root/runonce.sh

-1voto

JatSing Puntos 166

en redhat y debian sistemas puede hacerlo desde /etc/rc.local, es una especie de autoexec.bate.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: