J'apprécie vraiment l'effort fourni dans la réponse de Dennis Williamson . Je voulais l'accepter comme réponse à cette question, car elle est élégante et simple cependant:
- J'ai finalement pensé qu'il fallait trop d'étapes à mettre en place.
- Il nécessite un accès root.
Je pense que sa solution serait formidable en tant que fonctionnalité prête à l'emploi d'une distribution Linux.
Cela étant dit, j'ai écrit mon propre script pour accomplir plus ou moins la même chose que la solution de Dennis. Il ne nécessite aucune étape de configuration supplémentaire et ne nécessite pas d'accès 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
Enregistrer ce script (par exemple: runonce
), chmod +x
et exécution:
$ runonce foo
$ runonce "echo \"I'm up. I swear I'll never email you again.\" | mail -s \"Server's Up\" $(whoami)"
En cas de faute de frappe, vous pouvez supprimer une commande de la file d'attente runonce avec l'indicateur -r:
$ runonce fop
$ runonce -r fop
$ runonce foo
L'utilisation de sudo fonctionne comme vous vous y attendez. Utile pour démarrer un serveur une seule fois après le prochain redémarrage.
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"
Quelques notes:
- Ce script réplique l'environnement (PATH, répertoire de travail, utilisateur) dans lequel il a été appelé.
- Il est conçu pour différer essentiellement l'exécution d'une commande car elle serait exécutée "ici, maintenant" jusqu'à la prochaine séquence de démarrage.