Me gustaría programar un comando para que se ejecute después de reiniciar en una máquina Linux. Sé cómo hacer esto, así que el comandose ejecuta constantemente después de cada reiniciocon una @reboot
entrada crontab, sin embargo, solo quiero que el comando se ejecute una vez. Después de ejecutarse, debe eliminarse de la cola de comandos para ejecutar. Básicamente estoy buscando un equivalente de Linux aCorre una vezen el mundo de Windows.
En caso de que sea importante:
$ 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
¿Existe una forma sencilla y programable de hacer esto?
Respuesta1
Cree una @reboot
entrada en su crontab para ejecutar un script llamado /usr/local/bin/runonce
.
Cree una estructura de directorio llamada /etc/local/runonce.d/ran
usando mkdir -p
.
Cree el script /usr/local/bin/runonce
de la siguiente manera:
#!/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 cualquier script que desee ejecutar en el próximo reinicio (solo una vez) en el directorio /etc/local/runonce.d
y chown
hágalo chmod +x
correctamente. Una vez que se haya ejecutado, lo encontrará movido al ran
subdirectorio y la fecha y hora agregadas a su nombre. También habrá una entrada en tu syslog
.
Respuesta2
Realmente aprecio el esfuerzo puesto enLa respuesta de Dennis Williamson. Quería aceptarlo como la respuesta a esta pregunta, ya que es elegante y simple, sin embargo:
- Al final sentí que se necesitaban demasiados pasos para configurarlo.
- Requiere acceso root.
Creo que su solución sería excelente como característica lista para usar en una distribución de Linux.
Dicho esto, escribí mi propio guión para lograr más o menos lo mismo que la solución de Dennis. No requiere ningún paso de configuración adicional 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
Guarde este script (por ejemplo: runonce
), chmod +x
y ejecute:
$ runonce foo
$ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)"
En caso de un error tipográfico, puede eliminar un comando de la cola de ejecución única con el indicador -r:
$ runonce fop
$ runonce -r fop
$ runonce foo
El uso de sudo funciona de la forma esperada. Útil para iniciar un servidor sólo una vez después del siguiente 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:
- Este script replica el entorno (RUTA, directorio de trabajo, usuario) en el que fue invocado.
- Está diseñado básicamente para diferir la ejecución de un comando tal como se ejecutaría "aquí y ahora" hasta después de la siguiente secuencia de inicio.
Respuesta3
Crear, por ejemplo /root/runonce.sh
:
#!/bin/bash
#your command here
sed -i '/runonce.sh/d' /etc/rc.local
Añadir /etc/rc.local
:
/root/runonce.sh
Respuesta4
Solía chkconfig
hacer que mi sistema ejecutara automáticamente un script una vez después del arranque y nunca más. Si su sistema usa ckconfig (Fedora, RedHat, CentOs, etc.), esto funcionará.
Primero el guión:
#!/bin/bash
# chkconfig: 345 99 10
# description: This script is designed to run once and then never again.
#
##
# Beginning of your custom one-time commands
#
plymouth-set-default-theme charge -R
dracut -f
#
# End of your custom one-time commands
##
##
# This script will run once
# If you would like to run it again. run 'chkconfig run-once on' then reboot.
#
chkconfig run-once off
chkconfig --del run-once
- Nombra el guión
run-once
- Coloque el guión en
/etc/init.d/
- Habilitar el script
chkconfig run-once on
- reiniciar
Cuando el sistema arranca, su script se ejecutará una vez y nunca más.
Es decir, nunca más a menos que así lo desees. Siempre puedes volver a habilitar el script con el chkconfig run-once on
comando.
Me gusta esta solución porque coloca un solo archivo en el sistema y porque el comando ejecutar una vez se puede volver a emitir si es necesario.