Eu realmente aprecio o esforço feito na resposta de Dennis Williamson . Eu queria aceitá-lo como resposta a esta pergunta, pois é elegante e simples, no entanto:
- Por fim, senti que eram necessárias muitas etapas para configurar.
- Requer acesso root.
Eu acho que sua solução seria ótima como um recurso pronto para uso em uma distribuição Linux.
Dito isto, escrevi meu próprio roteiro para realizar mais ou menos a mesma coisa que a solução de Dennis. Não requer etapas extras 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 esse 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 de runonce com o sinalizador -r:
$ runonce fop
$ runonce -r fop
$ runonce foo
O uso do sudo funciona da maneira que você esperaria. Ú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 chamado.
- Ele foi projetado para adiar basicamente a execução de um comando, como seria executado "aqui e agora" até depois da próxima sequência de inicialização.