Forcer un script bash à s'arrêter après une certaine durée


#1

Hello à toutes et tous.

Je viens de finir un script,
qui me permet d’utiliser ma Asus Tinkerboard
sous debian en remplacement de ma Livebox.

Les grosses étapes de ce script passent par une récupération des identifiants de connexion,
création d’une chaine hashée pour récupérer une adresse ip via le protocole dhcp d’Orange.

En temps normal, c’est à dire quand les identifiants sont bons,
la connexion me prend une minute en étant large.

Mais j’ai voulu tester le cas où je me trompe dans les identifiants,
Et la ça mouline pendant plusieurs minutes avant de tomber en échec.
Et encore, des fois ça mouline tout court.

Ce que je cherche à faire :
Imposer une durée à mon script et disons par exemple si au bout de 2minutes je n’ai pas de retour ou la fin du script, ça coupe tout.

quelqu’un aurais une idée??

Merci par avance

Voici le script pour les curieux :slight_smile:

Je vous préviens, je ne suis pas bon en script
et j’ai surement du faire des choses qui ne sont pas trop beau à voir :slight_smile:

Toutes les critiques sont bonnes à prendre :slight_smile:

#!/bin/bash
sudo python /diagbox/web/scripts/gpio/led_32_on.py

#Variables
readonly dhclient_files=/diagbox/web/tmp/dhclient.conf
readonly dhclient_def=/etc/dhcp/dhclient.conf

readonly error_log=/diagbox/web/tmp/error.log

readonly iptables_rescue=/etc/iptables.ipv4.nat.backup_rescue
readonly iptables_normal=/etc/iptables.ipv4.nat
readonly iptables_diagbox=/etc/iptables.ipv4.nat.backup_diagbox

readonly interfaces_rescue=/etc/network/interfaces_RESCUE
readonly interfaces_normal=/etc/network/interfaces
readonly interfaces_dhcp=/etc/network/interfaces_DHCP

readonly dhcpleases=/var/lib/dhcp/dhclient.orange.leases

readonly identifiant_origine=/diagbox/web/ini/id.txt
readonly identifiant_crypte=/diagbox/web/ini/id_crypte.txt
readonly identifiant_error=/diagbox/web/ini/error.txt

readonly clef_crypte=/diagbox/.MyKey
read mdp_crypte <$clef_crypte

#Fonctions
function fonction_id_supprimer
{
if [ -f $identifiant_origine ];then
	echo " suppression fichier id origine"
	sudo rm $identifiant_origine
fi

if [ -f $identifiant_crypte ];then
echo " suppression fichier id crypte"
	sudo rm $identifiant_crypte
fi
}

#Effacer les fichier tempo si presents
if [ -f $error_log ];then
	echo "Le log error existe déjà ";
	sudo rm $error_log
fi



if [ -f $dhclient_files ];then
	echo "Le fichier de configuration existe !"
	if sudo rm $dhclient_files; then
		echo "fichier dhclient efface"	
	else
		echo "Echec suppression tempo dhclient deja existant" >> $error_log
		sudo python /diagbox/web/scripts/gpio/led_32_off.py
		exit
	fi
fi

fonction_id_supprimer

#leases dhcp
if [ -f $dhcpleases ];then
	echo "Le fichier de configuration existe !"
	if sudo rm $dhcpleases; then
		echo "fichier dhclient leases"
	else
		echo "Echec suppression dhcp leases" >> $error_log
		sudo python /diagbox/web/scripts/gpio/led_32_off.py
		exit
	fi
fi

if sudo touch $dhcpleases; then
	echo "creation leases dhcp ok"
else
	echo "Echec creation leases dhcp" >> $error_log
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

#modprobe
if sudo modprobe 8021q; then
	echo "modprobe 8021q"
else
	echo "Echec modprobe 8021q" >> $error_log
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

#Modification interfaces eth0

if sudo ifconfig eth0 default;then
	echo "adresse eth0 enlevée"
else
	echo "Echec enlevement adresse ip eth0" >> $error_log
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

if sudo cp $interfaces_rescue $interfaces_normal; then
	echo 'configuration interfaces modifié'
else
	echo "Echec modification configuration ethO" >> $error_log
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


#fti conversion
spiderman=$1
thor=$2

login=$spiderman
pass=$thor

tohex() {
  for h in $(echo $1 | sed "s/\(.\)/\1 /g"); do printf %02x \'$h; done
}

addsep() {
  echo $(echo $1 | sed "s/\(.\)\(.\)/:\1\2/g")
}

r=$(dd if=/dev/urandom bs=1k count=1 2>&1 | md5sum | cut -c1-16)
id=${r:0:1}
h=3c12$(tohex ${r})0313$(tohex ${id})$(echo -n ${id}${pass}${r} | md5sum | cut -c1-32)

AUTHSTRING=00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d$(addsep $(tohex ${login})${h})
echo ${AUTHSTRING}

#Fichier dhclient
#Ecriture
if echo 'option rfc3118-authentication code 90 = string;' >> $dhclient_files; then
	echo "ok"
else
	echo "Echec écriture fichier dhclient partie 1" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

if echo "interface \"orange\" {" >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 2" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo "send vendor-class-identifier \"sagem\";" >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 3" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo "send user-class \"+FSVDSL_livebox.Internet.softathome.Livebox3\";" >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 4" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo "send rfc3118-authentication ${AUTHSTRING};" >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 5" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

if echo 'request subnet-mask, routers,' >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 6" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo 'domain-name, broadcast-address, dhcp-lease-time,' >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 7" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo 'dhcp-renewal-time, dhcp-rebinding-time,' >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 8" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo 'rfc3118-authentication;' >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 9" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo 'prepend domain-name-servers 8.8.8.8, 8.8.4.4;' >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 10" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


if echo '}' >> $dhclient_files; then
	echo "ok"
else
	"Echec écriture fichier dhclient partie 11" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi


#Deplacement 
if [ -f $dhclient_def ];then
	echo "Le fichier de configuration existe !";
	if sudo rm $dhclient_def; then
		echo "fichier dhclient efface"	
	else
		echo "Echec suppression dhclient deja existant" >> $error_log
		#retour interfaces en dhcp
		sudo cp $interfaces_dhcp $interfaces_normal
		#retour iptables
		sudo cp $iptables_diagbox $iptables_normal
		sudo rm $dhclient_files
		sudo rm $dhcpleases
		sudo python /diagbox/web/scripts/gpio/led_32_off.py
		exit
		fi
fi

if sudo cp $dhclient_files $dhclient_def; then
	echo 'fichier dhclient modifie';
else
	echo "Echec déplacement fichier dhclient" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

#iptables
if	sudo iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1; then
	echo "sudo iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1 ok"
else
	echo "echec sudo iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

if sudo cp $iptables_rescue $iptables_normal; then
	echo 'fichier iptables modifié';
else
	echo "Echec déplacement fichier iptables" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases
	sudo iptables-restore < /etc/iptables.ipv4.nat 
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

sudo iptables-restore < /etc/iptables.ipv4.nat

echo "[rescue]"	>>$identifiant_origine
echo "fti="$1 >>$identifiant_origine
echo "mdp="$2 >>$identifiant_origine

if sudo openssl enc -e -aes-256-cbc -in $identifiant_origine -out $identifiant_crypte -pass pass:$mdp_crypte;then
	echo "fichier crypté"
	sudo rm $identifiant_origine
else
	sudo rm $identifiant_origine
	echo "Echec cryptage fichier identifiant" >>$identifiant_error
fi




#Relancer la machine
if sudo ifup -a;then
	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	sudo python /diagbox/web/scripts/gpio/led_22_off.py
	sudo python /diagbox/web/scripts/gpio/led_24_off.py
	sudo python /diagbox/web/scripts/gpio/led_26_on.py
	echo "ifup ok"
else
	echo "Echec ifup ok" >> $error_log
	#retour interfaces en dhcp
	sudo cp $interfaces_dhcp $interfaces_normal
	#retour iptables
	sudo cp $iptables_diagbox $iptables_normal
	sudo rm $dhclient_files
	sudo rm $dhcpleases

	sudo python /diagbox/web/scripts/gpio/led_32_off.py
	exit
fi

#2

Il est beau à voir en tout cas.
Je n’aurais vraiment pas cru possible de pouvoir remplacer une box ! Bravo :wink:

Pour le délai, avec le PID du script, je vois un truc simple comme :

sleep 120 && kill [options] PID &

Par contre, je ne sais pas trop comment obtenir le PID…

pgrep [options] pattern ?

rem@n73sm ~ $ pgrep -u rem Captvty
5232
rem@n73sm ~ $ 
# update : une dernière qui me plait
sleep 120 && /bin/kill $( /usr/bin/pgrep -u rem Captvty ) 2>&1 &

Faut blinder un peu pour faire bien propre. Au cas où la connexion a réussi.

J’ai essayé de faire quelque chose de correct ; je débute avec les scripts.

#!/bin/bash
puser=rem # replace with your script run user
ppattern=Captvty # replace with your script name pattern
kdelay=20 # delay before killing script (in seconds)

/usr/bin/sleep $kdelay && \
        spid=$( /usr/bin/pgrep -u $puser $ppattern ) && \
        if ! [ -z "$spid" ]; then /bin/kill $spid; fi 2>&1 &


# place your script here

exit 0

#3

Bonjour,
Par curiosité, quel est le sens de :

spiderman=$1
thor=$2

login=$spiderman
pass=$thor

Bonne journée à tous :slight_smile:
Donut


#4

En shell, le PID courant est $$ et le PID du parent $PPID


#5

Hello.
J’éxecute mon script bash par l’intermédiaire d’un script php
( j’ai une interface web faite maison :slight_smile: ).

Du coup, c’est pour passer les paramètres du script php au script bash
(Spiderman et thor car mon fils en raffole :slight_smile: )


#6

Hello,
Merci pour ta réponse :slight_smile: :slight_smile:

Je vais travailler ce que tu me proposes :slight_smile:


#7

Hello @domoticity

Ce que j’ai fait avec pgrep ne sert plus à rien.

Tu tuerai le PID courant ou le PID du parent ? :thinking:
Je vais probablement faire des essais de mon côté.

Merci bien mattotop.

J’ai ça qui fonctionne :

#!/bin/bash
sleep 10 && kill $$ 2>&1 &
while :
do
    echo "."
    sleep 1
done
exit 0

Avec le PID du parent ($PPID) ça ne marche pas ;
le parent dans mon cas est le processus bash lui-même, ouvert dans mon terminal.
Car je lance les scripts tout bêtement avec :

$ ./monscript.sh

Je crois que ce n’est pas trop une bonne idée d’utiliser 2>&1 & en phase de test
car c’est peut-être trop silencieux pour voir les messages éventuels.
Utiliser un simple & peut suffire au début.

Et en plus je l’ai juste recopié d’un tuto sans bien comprendre…
Je me renseigne davantage alors :

Une astuce est de se rappeler que 1 = sortie standard, 2 = erreur standard. Alors :

2>&1 = le flux d’erreur standard passe dans le flux de sortie standard.
1>&2 = vice versa.

J’ai choisi de considérer l’esperluette (&) comme faisant référence
à l’“adresse” du descripteur de fichier existant.

Une esperluette afin que vous ne changiez pas le fichier lui-même
ou que vous n’en créiez pas un nouveau.

Il est facile de se le rappeler si vous avez déjà programmé en langage C

https://unix.stackexchange.com/questions/746/how-could-i-remember-how-to-use-redirection

Voir aussi https://www.debian-fr.org/t/dd-recuperer-lavancement/79639/10?u=r2mi

Mon but au début était de rendre la commande silencieuse
et en fin de compte je l’obtiens avec à minima :

sleep 10 && kill $$ > /dev/null &

Tant de jeunes années perdues ou presque avec l’interpréteur COMMAND.COM :disappointed_relieved:
Je n’ai plus le feu sacré que j’ai pu avoir.


#9

Salut

Mais du coup, c’était pas aussi simple de définir directement les variables ‘login’ et ‘pass’, sans passer par des variables intermédiaires ?
Comme ça, en gros:

login=$1
pass=$2

#10

Re-Salut

En fait, je fais le tour de ton script et il pourrait être très simplifié:

  • L’utilisation de ‘sudo’ à répétition dans le script me laisse penser qu’il serait plus judicieux de le lancer directement avec ‘sudo’ ou en tant que root. J’ajouterais juste une ligne de vérification en début de script pour couvrir ça:
[ "$(whoami)" != root ] && echo -e "Usage: './$(basename "$0")'  en tant que root ou en utilisant 'sudo'." && exit 1
  • L’édition du fichier ‘dhclient_files’ peut se faire en une commande au lieu de 11, surtout que ces 11 commandes sont simplement des ‘echo’ renvoyé en fin du fichier ‘dhclient_files’ (j’en profite pour ajouter une fonction ‘previous_conf_return’ qui t’évite de répéter ce bout de code au sein de ton script) [j’ai laissé les ‘sudo’ pour cette partie, puisque je n’ai pas encore eu ton avis sur le point précédent et qu’il est possible qu’il y ait un point bloquant que je n’aurais pas vu. Sans ‘sudo’ dans le script, on peut utiliser cat au lieu de echo, ce qui est un poil plus élégant.]:
previous_conf_return() {
    #retour interfaces en dhcp
    sudo cp $interfaces_dhcp $interfaces_normal
    #retour iptables
    sudo cp $iptables_diagbox $iptables_normal
    sudo rm $dhclient_files
    sudo rm $dhcpleases
    sudo python /diagbox/web/scripts/gpio/led_32_off.py
    exit
}

#Fichier dhclient
#Ecriture
echo -e "option rfc3118-authentication code 90 = string;
interface \"orange\" {
    send vendor-class-identifier \"sagem\";
    send user-class \"+FSVDSL_livebox.Internet.softathome.Livebox3\";
    send rfc3118-authentication ${AUTHSTRING};
    request subnet-mask, routers,
        domain-name, broadcast-address, dhcp-lease-time,
        dhcp-renewal-time, dhcp-rebinding-time,
        rfc3118-authentication;
    prepend domain-name-servers 8.8.8.8, 8.8.4.4;
}" | sudo tee -a $dhclient_files

if [ $? = 0 ] ; then
    echo "ok"
else
    "Echec ecriture fichier dhclient" >> $error_log
    previous_conf_return
    exit
fi

Avec ce genre de modifications, ton code sera plus fluide et ça risque de même avoir un temps de réponse amélioré.
Je regarde ça un peu plus en avant et je te donne une version “nettoyée” ce soir ou demain.


#11

Bon, alors, du coup, j’ai 2 versions à te proposer.

  1. On génère manuellement les messages d’erreur à coup de if […] ; then … ; else echo “$error” ; fi comme tu le fais dans ton script:
#!/usr/bin/env bash

#Check permissions
{ [ "$(whoami)" != root ] || [ -z "$2" ] ; } && echo -e "Usage: './$(basename "$0") <LOGIN> <PASSWORD>'  en tant que root ou en utilisant 'sudo'." && exit

python /diagbox/web/scripts/gpio/led_32_on.py

#Variables
login=$1
pass=$2

readonly dhclient_files=/diagbox/web/tmp/dhclient.conf
readonly dhclient_def=/etc/dhcp/dhclient.conf

readonly error_log=/diagbox/web/tmp/error.log

readonly iptables_rescue=/etc/iptables.ipv4.nat.backup_rescue
readonly iptables_normal=/etc/iptables.ipv4.nat
readonly iptables_diagbox=/etc/iptables.ipv4.nat.backup_diagbox

readonly interfaces_rescue=/etc/network/interfaces_RESCUE
readonly interfaces_normal=/etc/network/interfaces
readonly interfaces_dhcp=/etc/network/interfaces_DHCP

readonly dhcpleases=/var/lib/dhcp/dhclient.orange.leases

readonly identifiant_origine=/diagbox/web/ini/id.txt
readonly identifiant_crypte=/diagbox/web/ini/id_crypte.txt
readonly identifiant_error=/diagbox/web/ini/error.txt

readonly clef_crypte=/diagbox/.MyKey
read -r mdp_crypte <$clef_crypte


#Fonctions
tohex() {
    for h in $(echo "$1" | sed "s/\(.\)/\1 /g") ; do
        printf %02x \'"$h"
    done
}

addsep() {
    echo "$1" | sed "s/\(.\)\(.\)/:\1\2/g"
}

previous_conf_return() {
    #retour interfaces en dhcp
    cp $interfaces_dhcp $interfaces_normal
    #retour iptables
    cp $iptables_diagbox $iptables_normal
    rm $dhclient_files
    rm $dhcpleases
    python /diagbox/web/scripts/gpio/led_32_off.py
    exit
}


#Effacer les fichier tempo si presents
if [ -f $error_log ] ; then
    echo "Le log error existe deja"
    rm $error_log
fi

if [ -f $dhclient_files ] ; then
    echo "Le fichier de configuration existe !"
    if rm $dhclient_files ; then
        echo "fichier dhclient efface"
    else
        echo "Echec suppression tempo dhclient deja existant" >> $error_log
        python /diagbox/web/scripts/gpio/led_32_off.py
        exit
    fi
fi

#Suppression des id
if [ -f $identifiant_origine ] ; then
    echo "Suppression fichier id origine"
    rm $identifiant_origine
fi

if [ -f $identifiant_crypte ] ; then
    echo "Suppression fichier id crypte"
    rm $identifiant_crypte
fi

#leases dhcp
if [ -f $dhcpleases ] ; then
    echo "Le fichier de configuration existe !"
    if rm $dhcpleases ; then
        echo "fichier dhclient leases"
    else
        echo "Echec suppression dhcp leases" >> $error_log
        python /diagbox/web/scripts/gpio/led_32_off.py
        exit
    fi
fi

if touch $dhcpleases ; then
    echo "creation leases dhcp ok"
else
    echo "Echec creation leases dhcp" >> $error_log
    python /diagbox/web/scripts/gpio/led_32_off.py
    exit
fi

#modprobe
if modprobe 8021q ; then
    echo "modprobe 8021q"
else
    echo "Echec modprobe 8021q" >> $error_log
    python /diagbox/web/scripts/gpio/led_32_off.py
    exit
fi

#Modification interfaces eth0
if ifconfig eth0 default ; then
    echo "adresse eth0 enlevee"
else
    echo "Echec enlevement adresse ip eth0" >> $error_log
    python /diagbox/web/scripts/gpio/led_32_off.py
    exit
fi

if cp $interfaces_rescue $interfaces_normal ; then
    echo 'configuration interfaces modifiee'
else
    echo "Echec modification configuration ethO" >> $error_log
    python /diagbox/web/scripts/gpio/led_32_off.py
    exit
fi


#fti conversion
r=$(dd if=/dev/urandom bs=1k count=1 2>&1 | md5sum | cut -c1-16)
id=${r:0:1}
h=3c12$(tohex "${r}")0313$(tohex "${id}")$(echo -n "${id}""${pass}""${r}" | md5sum | cut -c1-32)

AUTHSTRING=00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d$(addsep "$(tohex "${login}")${h}")
echo "${AUTHSTRING}"

#Fichier dhclient
#Ecriture
cat << EOF >> $dhclient_files
option rfc3118-authentication code 90 = string;
interface "orange" {
    send vendor-class-identifier "sagem";
    send user-class "+FSVDSL_livebox.Internet.softathome.Livebox3";
    send rfc3118-authentication ${AUTHSTRING};
    request subnet-mask, routers,
        domain-name, broadcast-address, dhcp-lease-time,
        dhcp-renewal-time, dhcp-rebinding-time,
        rfc3118-authentication;
    prepend domain-name-servers 8.8.8.8, 8.8.4.4;
}
EOF

if [ $? = 0 ] ; then
    echo "ok"
else
    "Echec ecriture fichier dhclient" >> $error_log
    previous_conf_return
fi

#Deplacement
if [ -f $dhclient_def ] ; then
    echo "Le fichier de configuration existe !"
    if rm $dhclient_def ; then
        echo "Fichier dhclient efface"
    else
        echo "Echec suppression dhclient deja existant" >> $error_log
        previous_conf_return
    fi
fi

if cp $dhclient_files $dhclient_def ; then
    echo "Fichier dhclient modifie"
else
    echo "Echec deplacement fichier dhclient" >> $error_log
    previous_conf_return
fi

#iptables
if iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1 ; then
    echo "iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1 ok"
else
    echo "Echec iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1" >> $error_log
    previous_conf_return
fi

if cp $iptables_rescue $iptables_normal; then
    echo "Fichier iptables modifie";
else
    echo "Echec deplacement fichier iptables" >> $error_log
    previous_conf_return
fi

iptables-restore < /etc/iptables.ipv4.nat

cat << EOF >> $identifiant_origine
[rescue]
    fti=$login
    mdp=$pass
EOF

if openssl enc -e -aes-256-cbc -in $identifiant_origine -out $identifiant_crypte -pass pass:"$mdp_crypte" ; then
    echo "Fichier crypte"
else
    echo "Echec cryptage fichier identifiant" >> $identifiant_error
    # previous_conf_return
fi

rm $identifiant_origine

#Relancer la machine
if ifup -a ; then
    python /diagbox/web/scripts/gpio/led_32_off.py
    python /diagbox/web/scripts/gpio/led_22_off.py
    python /diagbox/web/scripts/gpio/led_24_off.py
    python /diagbox/web/scripts/gpio/led_26_on.py
    echo "ifup ok"
else
    echo "Echec ifup ok" >> $error_log
    previous_conf_return
fi
  1. On ‘piège’ les erreurs qui déclenche une sortie et un affichage de la commande qui a échoué (cf #Trap errors). Ca permet de rendre la chose un peu plus compacte. Dans ton cas, il y a cette double sortie en erreur: sortie simple et sortie avec restauration de la config précédente. Il peut être possible de compacter encore plus la chose pour faire que la sortie en erreur fasse toujours une restauration de la config précédente, ce qui t’évite de faire des ‘echo’ personnalisés de toutes tes erreurs, le piège s’en chargeant pour toi. Mais j’ai préférer conserver ton schéma de double sortie pour cette proposition:
#!/usr/bin/env bash

#Check permissions
{ [ "$(whoami)" != root ] || [ -z "$2" ] ; } && echo -e "Usage: './$(basename "$0") <LOGIN> <PASSWORD>'  en tant que root ou en utilisant 'sudo'." && exit

#Trap errors
set -e
trap 'last_command=$BASH_COMMAND' DEBUG
trap_exit() {
    ret=$?
    if [ $ret -ne 0 ]; then
        echo "[ERROR] '${last_command}' a echoue avec l'exit code ${ret}." >> "$error_log" && python /diagbox/web/scripts/gpio/led_32_off.py
    fi
}
trap 'trap_exit;' EXIT


#Variables
login=$1
pass=$2

readonly dhclient_files=/diagbox/web/tmp/dhclient.conf
readonly dhclient_def=/etc/dhcp/dhclient.conf

readonly error_log=/diagbox/web/tmp/error.log

readonly iptables_rescue=/etc/iptables.ipv4.nat.backup_rescue
readonly iptables_normal=/etc/iptables.ipv4.nat
readonly iptables_diagbox=/etc/iptables.ipv4.nat.backup_diagbox

readonly interfaces_rescue=/etc/network/interfaces_RESCUE
readonly interfaces_normal=/etc/network/interfaces
readonly interfaces_dhcp=/etc/network/interfaces_DHCP

readonly dhcpleases=/var/lib/dhcp/dhclient.orange.leases

readonly identifiant_origine=/diagbox/web/ini/id.txt
readonly identifiant_crypte=/diagbox/web/ini/id_crypte.txt
readonly identifiant_error=/diagbox/web/ini/error.txt

readonly clef_crypte=/diagbox/.MyKey
read -r mdp_crypte <$clef_crypte


#Fonctions
tohex() {
    for h in $(echo "$1" | sed "s/\(.\)/\1 /g") ; do
        printf %02x \'"$h"
    done
}

addsep() {
    echo "$1" | sed "s/\(.\)\(.\)/:\1\2/g"
}

previous_conf_return() {
    echo "[ERROR] '${last_command}' a echoue avec l'exit code ${ret}."
    #retour interfaces en dhcp
    cp $interfaces_dhcp $interfaces_normal
    #retour iptables
    cp $iptables_diagbox $iptables_normal
    rm $dhclient_files
    rm $dhcpleases
    python /diagbox/web/scripts/gpio/led_32_off.py

    exit
}


python /diagbox/web/scripts/gpio/led_32_on.py

#Effacer les fichier tempo si presents
if [ -f $error_log ] ; then
    echo "Le log error existe deja"
    rm $error_log
fi

if [ -f $dhclient_files ] ; then
    echo "Le fichier de configuration existe !"
    rm $dhclient_files
fi

#Suppression des id
if [ -f $identifiant_origine ] ; then
    echo "Suppression fichier id origine"
    rm $identifiant_origine
fi

if [ -f $identifiant_crypte ] ; then
    echo "Suppression fichier id crypte"
    rm $identifiant_crypte
fi

#leases dhcp
if [ -f $dhcpleases ] ; then
    echo "Le fichier de configuration existe !"
    rm $dhcpleases
fi

touch $dhcpleases

#modprobe
modprobe 8021q

#Modification interfaces eth0
ifconfig eth0 default

cp $interfaces_rescue $interfaces_normal


#fti conversion
r=$(dd if=/dev/urandom bs=1k count=1 2>&1 | md5sum | cut -c1-16)
id=${r:0:1}
h=3c12$(tohex "${r}")0313$(tohex "${id}")$(echo -n "${id}""${pass}""${r}" | md5sum | cut -c1-32)

AUTHSTRING=00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d$(addsep "$(tohex "${login}")${h}")
echo "${AUTHSTRING}"

#Fichier dhclient
#Ecriture
cat << EOF >> $dhclient_files
option rfc3118-authentication code 90 = string;
interface "orange" {
    send vendor-class-identifier "sagem";
    send user-class "+FSVDSL_livebox.Internet.softathome.Livebox3";
    send rfc3118-authentication ${AUTHSTRING};
    request subnet-mask, routers,
        domain-name, broadcast-address, dhcp-lease-time,
        dhcp-renewal-time, dhcp-rebinding-time,
        rfc3118-authentication;
    prepend domain-name-servers 8.8.8.8, 8.8.4.4;
}
EOF

#Deplacement
if [ -f $dhclient_def ] ; then
    echo "Le fichier de configuration existe !"
    if rm $dhclient_def ; then
        echo "Fichier dhclient efface"
    else
        echo "Echec suppression dhclient deja existant" >> $error_log
        previous_conf_return
    fi
fi

if cp $dhclient_files $dhclient_def ; then
    echo "Fichier dhclient modifie"
else
    echo "Echec deplacement fichier dhclient" >> $error_log
    previous_conf_return
fi

#iptables
if iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1 ; then
    echo "iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1 ok"
else
    echo "Echec iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1" >> $error_log
    previous_conf_return
fi

if cp $iptables_rescue $iptables_normal; then
    echo "Fichier iptables modifie";
else
    echo "Echec deplacement fichier iptables" >> $error_log
    previous_conf_return
fi

iptables-restore < /etc/iptables.ipv4.nat

cat << EOF >> $identifiant_origine
[rescue]
    fti=$login
    mdp=$pass
EOF

openssl enc -e -aes-256-cbc -in $identifiant_origine -out $identifiant_crypte -pass pass:"$mdp_crypte"

rm $identifiant_origine

#Relancer la machine
if ifup -a ; then
    python /diagbox/web/scripts/gpio/led_32_off.py
    python /diagbox/web/scripts/gpio/led_22_off.py
    python /diagbox/web/scripts/gpio/led_24_off.py
    python /diagbox/web/scripts/gpio/led_26_on.py
    echo "ifup ok"
else
    echo "Echec ifup ok" >> $error_log
    previous_conf_return
fi


En fait, comme je ne peux pas reposter de suite (3 réponses dans ce fil dont une que j’avais mal placé et, du coup, supprimé mais qu’il faut attendre 24h pour qu’elle le soit … :confused:) , j’ajoute la version 3 avec toutes les erreurs qui restaurent la config précédente. Gros avantage de ce procédé, à chaquefois que tu ajoute une commande dans ton code, si celle-ci part en erreur, c’est le ‘piège’ qui se charge de tout, pas besoin de lui redéfinir un retour d’erreur perso par un echo. Autre avantage lié, ton code comporte moins de lignes et d’ensembles conditionnels susceptibles de partir en erreur :

#!/usr/bin/env bash

#Check permissions
{ [ "$(whoami)" != root ] || [ -z "$2" ] ; } && echo -e "Usage: './$(basename "$0") <LOGIN> <PASSWORD>'  en tant que root ou en utilisant 'sudo'." && exit


#Fonctions
tohex() {
    for h in $(echo "$1" | sed "s/\(.\)/\1 /g") ; do
        printf %02x \'"$h"
    done
}

addsep() {
    echo "$1" | sed "s/\(.\)\(.\)/:\1\2/g"
}

previous_conf_return() {
    echo "[ERROR] '${last_command}' a echoue avec l'exit code ${ret}."
    #retour interfaces en dhcp
    cp "$interfaces_dhcp" "$interfaces_normal"
    #retour iptables
    cp "$iptables_diagbox" "$iptables_normal"
    rm "$dhclient_files"
    rm "$dhcpleases"
    python /diagbox/web/scripts/gpio/led_32_off.py
}


#Trap errors
set -e
trap 'last_command=$BASH_COMMAND' DEBUG
trap_exit() {
    ret=$?
    if [ $ret -ne 0 ]; then
        previous_conf_return
    fi
}
trap 'trap_exit;' EXIT


#Variables
login=$1
pass=$2

readonly dhclient_files=/diagbox/web/tmp/dhclient.conf
readonly dhclient_def=/etc/dhcp/dhclient.conf

readonly error_log=/diagbox/web/tmp/error.log

readonly iptables_rescue=/etc/iptables.ipv4.nat.backup_rescue
readonly iptables_normal=/etc/iptables.ipv4.nat
readonly iptables_diagbox=/etc/iptables.ipv4.nat.backup_diagbox

readonly interfaces_rescue=/etc/network/interfaces_RESCUE
readonly interfaces_normal=/etc/network/interfaces
readonly interfaces_dhcp=/etc/network/interfaces_DHCP

readonly dhcpleases=/var/lib/dhcp/dhclient.orange.leases

readonly identifiant_origine=/diagbox/web/ini/id.txt
readonly identifiant_crypte=/diagbox/web/ini/id_crypte.txt
readonly identifiant_error=/diagbox/web/ini/error.txt

readonly clef_crypte=/diagbox/.MyKey
read -r mdp_crypte <$clef_crypte


python /diagbox/web/scripts/gpio/led_32_on.py

#Effacer les fichier tempo si presents
[ -f $error_log ] && echo "Le log error existe deja" && rm $error_log

[ -f $dhclient_files ] && echo "Le fichier de configuration existe !" && rm $dhclient_files

#Suppression des id
[ -f $identifiant_origine ] && echo "Suppression fichier id origine" && rm $identifiant_origine

[ -f $identifiant_crypte ] && echo "Suppression fichier id crypte" && rm $identifiant_crypte

#leases dhcp
[ -f $dhcpleases ] && echo "Le fichier de configuration existe !" && rm $dhcpleases

touch $dhcpleases

#modprobe
modprobe 8021q

#Modification interfaces eth0
ifconfig eth0 default

cp $interfaces_rescue $interfaces_normal


#fti conversion
r=$(dd if=/dev/urandom bs=1k count=1 2>&1 | md5sum | cut -c1-16)
id=${r:0:1}
h=3c12$(tohex "${r}")0313$(tohex "${id}")$(echo -n "${id}""${pass}""${r}" | md5sum | cut -c1-32)

AUTHSTRING=00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d$(addsep "$(tohex "${login}")${h}")
echo "${AUTHSTRING}"

#Fichier dhclient
#Ecriture
cat << EOF >> $dhclient_files
option rfc3118-authentication code 90 = string;
interface "orange" {
    send vendor-class-identifier "sagem";
    send user-class "+FSVDSL_livebox.Internet.softathome.Livebox3";
    send rfc3118-authentication ${AUTHSTRING};
    request subnet-mask, routers,
        domain-name, broadcast-address, dhcp-lease-time,
        dhcp-renewal-time, dhcp-rebinding-time,
        rfc3118-authentication;
    prepend domain-name-servers 8.8.8.8, 8.8.4.4;
}
EOF

#Deplacement
[ -f $dhclient_def ] && echo "Le fichier de configuration existe !" && rm $dhclient_def

cp $dhclient_files $dhclient_def

#iptables
iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1

cp $iptables_rescue $iptables_normal

iptables-restore < /etc/iptables.ipv4.nat

cat << EOF >> $identifiant_origine
[rescue]
    fti=$login
    mdp=$pass
EOF

openssl enc -e -aes-256-cbc -in $identifiant_origine -out $identifiant_crypte -pass pass:"$mdp_crypte"

rm $identifiant_origine

#Relancer la machine
if ifup -a ; then
    python /diagbox/web/scripts/gpio/led_32_off.py
    python /diagbox/web/scripts/gpio/led_22_off.py
    python /diagbox/web/scripts/gpio/led_24_off.py
    python /diagbox/web/scripts/gpio/led_26_on.py
    echo "ifup ok"
else
    echo "Echec ifup ok" >> $error_log
    previous_conf_return
fi

#12

Hello,
Merci pour vos réponses :slight_smile:
Désolé de mettre du temps à répondre et surtout à vous remercier mais entre le boulot et la chaleur :slight_smile:

Ce weekend je regarderai vos propositions pour essayer de les comprendre et les adapter à mon script.

Merci encore


#13

Hello,
J’ai essayé mais ça n’avait pas abouti.
après peut être que je m’étais planté quelque part,
Je fais encore pas mal d’erreurs mais on apprends ainsi je pense :slight_smile:
Et des fois j’arrive à faire tourner un script sans savoir comment et la je me dis,
dans mon ordi il doit y avoir un ange gardien :slight_smile:


#14

J’avoue que , n’ayant pas un dispositif de remplacement de box similaire sous le coude, je n’ai pas pu tester si ça fonctionnait correctement en conditions réelles. Je me suis juste assuré que les retours de commandes une à une soient cohérents avec ce qui était attendu dans le script d’origine.

Le truc avec les variables intermédiaires ‘spiderman’ et ‘thor’, c’est qu’elles n’étaient pas utilisées dans le script. Tu réinjectais directement $1 et $2 dans les commandes à suivre. Du coup, j’ai zappé les variables intermédiaires et poussé les variables de base ‘login’ et ‘pass’ au lieu de $1 et $2 (plus claires pour la compréhension du script en relecture).

De même, pour avoir une bonne lecture des valeurs des variables, j’ai encadré des ‘$ma_variable’ de double-quotes à pas mal d’endroits du script (ça évite qu’une valeur de variable ne soit comprise que partiellement par le script à cause d’un caractère spécial qui scinde la valeur lue).

Après, l’idée principale de la réduction du volume de code que je te propose tient surtout au fait que tu avais pas mal de blocs de code qui se répètent. En faire une fonction qui sera appelée plusieurs fois rend surtout ton script plus facile à maintenir par la suite: une modif de ce bloc de commandes ne sera à faire qu’une fois dans le script si tu l’as déporté dans une fonction, alors qu’autrement, tu dois répéter l’opération pour chaque bloc similaire et tu risques d’en oublier un ou de faire une erreur sur un des blocs répétés.