Gostaria de agendar um comando para ser executado após a reinicialização em uma caixa Linux. Eu sei como fazer isso, então o comandoé executado consistentemente após cada reinicializaçãocom uma @reboot
entrada crontab, no entanto, quero que o comando seja executado apenas uma vez. Depois de executado, ele deve ser removido da fila de comandos para execução. Estou essencialmente procurando um equivalente Linux paraExecutar Uma Vezno mundo Windows.
Caso seja 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 uma maneira fácil e programável de fazer isso?
Responder1
Crie uma @reboot
entrada no seu crontab para executar um script chamado /usr/local/bin/runonce
.
Crie uma estrutura de diretórios chamada /etc/local/runonce.d/ran
usando mkdir -p
.
Crie o script /usr/local/bin/runonce
da seguinte maneira:
#!/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
Agora coloque qualquer script que você deseja executar na próxima reinicialização (apenas uma vez) no diretório /etc/local/runonce.d
e chown
execute- chmod +x
o apropriadamente. Depois de executado, você o verá movido para o ran
subdiretório e a data e hora anexadas ao seu nome. Haverá também uma entrada no seu arquivo syslog
.
Responder2
Eu realmente aprecio o esforço colocadoA resposta de Dennis Williamson. Eu queria aceitá-lo como resposta a esta pergunta, pois é elegante e simples:
- No final das contas, senti que eram necessárias muitas etapas para configurar.
- Requer acesso root.
Acho que a solução dele seria ótima como um recurso pronto para uso de uma distribuição Linux.
Dito isto, escrevi meu próprio script para realizar mais ou menos a mesma coisa que a solução de Dennis. Não requer nenhuma etapa extra de configuração e não requer acesso 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
Salve este script (por exemplo: runonce
), chmod +x
e execute:
$ runonce foo
$ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)"
No caso de um erro de digitação, você pode remover um comando da fila runonce com o sinalizador -r:
$ runonce fop
$ runonce -r fop
$ runonce foo
Usar o sudo funciona da maneira que você espera que funcione. Útil para iniciar um servidor apenas uma vez após a próxima reinicialização.
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"
Algumas notas:
- Este script replica o ambiente (PATH, diretório de trabalho, usuário) em que foi invocado.
- Ele foi projetado basicamente para adiar a execução de um comando, pois seria executado "aqui e agora" até depois da próxima sequência de inicialização.
Responder3
Crie, por exemplo /root/runonce.sh
:
#!/bin/bash
#your command here
sed -i '/runonce.sh/d' /etc/rc.local
Adicionar à /etc/rc.local
:
/root/runonce.sh
Responder4
Eu costumava chkconfig
fazer meu sistema executar automaticamente um script uma vez após a inicialização e nunca mais. Se o seu sistema usa ckconfig (Fedora, RedHat, CentOs, etc), isso funcionará.
Primeiro o roteiro:
#!/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
- Dê um nome ao roteiro
run-once
- Coloque o roteiro em
/etc/init.d/
- Habilite o script
chkconfig run-once on
- reinício
Quando o sistema inicializar, seu script será executado uma vez e nunca mais.
Isto é, nunca mais, a menos que você queira. Você sempre pode reativar o script com o chkconfig run-once on
comando.
Gosto desta solução porque ela coloca um e apenas um arquivo no sistema e porque o comando run-once pode ser reemitido, se necessário.