Le premier script de démarrage important est /etc/init.d/rc. Le script /etc/init.d/rc est créé en lançant la commande suivante:
cat > /etc/init.d/rc << "EOF"
#!/bin/sh
# Début /etc/init.d/rc
#
# Par Jason Pearce - jason.pearce@linux.org
# Modifié par Gerard Beekmans - gerard@linuxfromscratch.org
# print_error_msg basé sur des idées de Simon Perreault -
# nomis80@videotron.ca
#
#
# Inclut les fonctions déclarées dans le fichier /etc/init.d/functions
#
source /etc/init.d/functions
#
# La fonction print_error_msg affiche un message d'erreur quand survient une
# erreur imprévue qui, pour une raison ou une autre n'a pas été captée par
# l'appel à evaluate_retval ou encore par la vérification d'erreur.
#
print_error_msg()
{
echo
$FAILURE
echo -n "Vous ne devriez par lire ce message d'erreur. Cela indique "
echo "qu'il y a une erreur "
echo -n "imprévue et que le script $i s'est arrêté avec une"
echo "la valeur de retour "
echo -n "$error_value une raison inconnue. Si vous êtes capable de "
echo "relier cette erreur "
echo -n "à un bogue dans un des fichiers de ce livre, ça serait "
echo "sympa de nous en "
echo -n "informer à lfs-dev@linuxfromscratch.org"
$NORMAL
echo
echo
echo "Pressez une touche pour continuer..."
read
}
#
# Si vous retirez les commentaires devant la variable debug ci-dessous, aucun
# des scripts ne sera exécuté, seuls les noms des scripts ainsi que leurs
# paramètres seront affichés à l'écran de telle sorte que vous puissiez
# voir comment ils sont appelés par rc.
#
# Retirez les commentaire ci-dessous pour le débogage.
# debug=echo
#
# Lancement du script ou du programme.
#
startup() {
$debug "$@"
}
#
# Ignore CTRL-C seulement dans ce shell, de telle sorte que
# nous puissions interrompre les sous-processus.
#
trap ":" INT QUIT TSTP
#
# Recherche de l'état actuel du niveau d'exécution ("runlevel") et
# du précédent. La variable $RUNLEVEL est renseignée par init pour tous
# ses fils. Ce script tourne en tant que fils d'init.
#
runlevel=$RUNLEVEL
#
# Récupération du premier argument. Si aucun niveau d'exécution n'est
# passé au script, nous ne changerons pas les niveaux d'exécution.
#
[ "$1" != "" ] && runlevel=$1
if [ "$runlevel" = "" ]
then
echo "Usage: $0 <runlevel>" >&2
exit 1
fi
#
# Idem pour $PREVLEVEL (voir au-dessous pour $RUNLEVEL). Cette variable
# accueillera la valeur du précédent niveau d'exécution. Si $PREVLEVEL
# n'a pas de valeur, cela signifie qu'il n'y a pas de niveau
# d'exécution précédent, nous mettons alors la valeur du précédent à N.
#
previous=$PREVLEVEL
[ "$previous" = "" ] && previous=N
export runlevel previous
#
# Existe-il un répertoire rc pour le nouveau niveau d'exécution ?
#
if [ -d /etc/rc$runlevel.d ]
then
#
# Si ce n'est pas le cas, on collecte d'abord tous les scripts K*
# dans le nouveau niveau.
#
if [ $previous != N ]
then
for i in /etc/rc$runlevel.d/K*
do
[ ! -f $i ] && continue
#
# Le suffixe de la variable contiendra le nom du script sans l'en-tête
# Kxxx
#
suffix=${i#/etc/rc$runlevel.d/K[0-9][0-9][0-9]}
#
# S'il y a un script de départ pour ce script K dans le niveau précédent,
# on détermine quel est son chemin complet
#
previous_start=/etc/rc$previous.d/S[0-9][0-9][0-9]$suffix
#
# S'il n'y a pas de niveau précédent, c'est peut-être parce que quelque chose
# a pu être demarré dans rcS.d (niveau sysinit), donc nous allons déterminer
# le chemin dans cette éventualité.
#
sysinit_start=/etc/rcS.d/S[0-9][0-9][0-9]$suffix
#
# Arrêt du service s'il existe un script de départ dans le niveau d'exécution
# précédent ou dans le niveau sysinit. Si previous_start ou sysinit_start
# n'existent pas, la commande "continue" est lancée, cela force le script
# à interrompre cette itération de la boucle for et à continuer avec la
# prochaine itération.
# On se ramène à ce que ça ne lancera pas les commandes après les deux
# prochaines lines et recommencera ci-dessus pour une boucle. Voir
# le manuel de Bash pour plus d'information.
#
[ ! -f $previous_start ] &&
[ ! -f $sysinit_start ] && continue
#
# Si nous avons trouvé previous_start ou sysinit_start, lancement du
# script K
#
startup $i stop
error_value=$?
#
# Si la valeur retournée par le script n'est pas 0, quelque chose s'est mal
# passé avec le vérificateur d'erreur dans le script. La fonction
# print_error_msg est appelée et le message adapté ainsi que la valeur
# retournée par le script K sont affichés à l'écran.
#
if [ $error_value != 0 ]
then
print_error_msg
fi
done
fi
#
# Maintenant, lancement du script START pour ce niveau d'exécution
#
for i in /etc/rc$runlevel.d/S*
do
[ ! -f $i ] && continue
if [ $previous != N ]
then
#
# Chercher le script de départ dans le niveau d'exécution précédent et
# arrêter le script dans ce niveau.
#
suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9][0-9]}
stop=/etc/rc$runlevel.d/K[0-9][0-9][0-9]$suffix
previous_start=/etc/rc$previous.d/S[0-9][0-9][0-9]$suffix
#
# S'il y a un script de départ dans le niveau précédent et aucun script d'arrêt
# dans ce niveau, nous n'avons pas à relancer le service; interruption de cette
# itération et lancement de la suivante.
#
[ -f $previous_start ] && [ ! -f $stop ] && continue
fi
case "$runlevel" in
0|6)
#
# Les niveaux 0 et 6 sont des niveaux d'arrêt et de redémarrage. Nous ne
# commençons pas vraiment quoi que ce soit ici alors nous passons le paramètre
# "stop".
#
startup $i stop
error_value=$?
#
# Si la valeur retournée par le script n'est pas 0, quelque chose s'est mal
# passé avec le vérificateur d'erreur dans le script. La fonction
# print_error_msg est appelée et le message adapté ainsi que la valeur
# retournée par le script K sont affichés à l'écran.
#
if [ $error_value != 0 ]
then
print_error_msg
fi
;;
*)
startup $i start
error_value=$?
#
# Si la valeur retournée par le script n'est pas 0, quelque chose s'est mal
# passé avec le vérificateur d'erreur dans le script. La fonction
# print_error_msg est appelée et le message adapté ainsi que la valeur
# retournée par le script K sont affichés à l'écran.
#
if [ $error_value != 0 ]
then
print_error_msg
fi
;;
esac
done
fi
# Fin /etc/init.d/rc
EOF |