# Script au démarrage

**URL:** <https://www.debian-fr.org/t/script-au-demarrage/52850>\
**Category:** Programmation\
**Created:** [Février 21, 2016, 11:39 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850 "2016-02-21T11:39:34Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![d2d2](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@d2d2](https://www.debian-fr.org/u/d2d2)\
**Post date:** [Février 21, 2016, 11:39 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/1 "2016-02-21T11:39:34Z")

</div>

Je voudrais que ces deux commandes soient lancées automatiquement après chaque démarrage (à la fin de la séquence de démarrage) pour éviter d’avoir à débrancher/rebrancher physiquement mon modem usb :

`sh -c "echo 0 > /sys/bus/usb/devices/2-6/authorized"
sh -c "echo 1 > /sys/bus/usb/devices/2-6/authorized"`

J’ai testé ces commandes avec succès dans un terminal ; j’aimerais les lancer avec /etc/rc.local à la fin de la séquence de démarrage.

Je suis une bille en écriture de script 😢 alors merci d’avance pour votre aide 😃

dd

---

<div class="post-metadata">

**Author:** ![d2d2](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@d2d2](https://www.debian-fr.org/u/d2d2)\
**Post date:** [Février 21, 2016, 11:42 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/2 "2016-02-21T11:42:55Z")

</div>

Preuve que je suis nul, en ajoutant la commande à la fin de mon rc.local, ça fait le job ! le modem fait un reset et je n’ai pas besoin de débrancher le câble et rebrancher ![:041](https://www.debian-fr.org/uploads/default/original/1X/bfe857c9119752799c3eac55ca37a50312c51282.gif "applaudit")

Pour le coup je me demande si on pourrait améliorer un peu tout ça.

Le but est de faire un reset de mon modem usb Analog Devices Canada…

`root@ordi:/home/sww# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 002: ID 0603:00f2 Novatek Microelectronics Corp. 
Bus 002 Device 003: ID 045e:0040 Microsoft Corp. Wheel Mouse Optical
Bus 002 Device 005: ID 1110:900f Analog Devices Canada, Ltd (Allied Telesyn) AT-AR215 DSL Modem
`

Dans ma logique, je suppose qu’il faudrait :

1/ tester que le modem ID 1110:900f est branché à l’ordi (si non sortir du script)  
avec une commande genre lsusb ??

2/ trouver sur quel port  
avec quelque chose de ce genre là ??

`for X in /sys/bus/usb/devices/*; do 
    echo "$X"
    cat "$X/idVendor" 2>/dev/null 
    cat "$X/idProduct" 2>/dev/null
    echo
done`

3/ faire un reset sur le bon port

`sh -c "echo 0 > /sys/bus/usb/devices/port_du_modem/authorized"
sh -c "echo 1 > /sys/bus/usb/devices/port_du_modem/authorized"`

4/attendre un peu et tester que le modem est prêt à être lancé avec pppd  
en cherchant «&nbsp;modem operational&nbsp;» dans les logs ?? avec quelque chose comme ça ??

`root@ordi:/home/sww# dmesg | grep ueagle
[8.589372] [ueagle-atm] driver ueagle 1.4 loaded
[8.589395] usb 2-6: [ueagle-atm] ADSL device founded vid (0X1110) pid (0X9010) Rev (0X4000): Eagle I
[8.967036] usb 2-6: [ueagle-atm] pre-firmware device, uploading firmware
[8.967092] usb 2-6: [ueagle-atm] loading firmware ueagle-atm/eagleI.fw
[8.967128] usbcore: registered new interface driver ueagle-atm
[10.903039] usb 2-6: [ueagle-atm] firmware uploaded
[13.636079] usb 2-6: [ueagle-atm] ADSL device founded vid (0X1110) pid (0X900F) Rev (0X4006): Eagle I
[14.069036] usb 2-6: [ueagle-atm] using iso mode
[14.072059] usb 2-6: [ueagle-atm] (re)booting started
[15.533033] usb 2-6: [ueagle-atm] ATU-R firmware version : 44e2ea17
[15.535267] usb 2-6: [Ueagle-atm] requesting firmware ueagle-atm/CMVep.bin.v2 failed, try to get older cmvs
[15.603032] usb 2-6: [ueagle-atm] modem started, waiting synchronization...
[23.418194] usb 2-6: [ueagle-atm] ADSL device removed
[23.636180] usb 2-6: [ueagle-atm] ADSL device founded vid (0X1110) pid (0X900F) Rev (0X4006): Eagle I
[24.070041] usb 2-6: [ueagle-atm] using iso mode
[24.073068] usb 2-6: [ueagle-atm] (re)booting started
[25.502047] usb 2-6: [ueagle-atm] ATU-R firmware version : 44e2ea17
[25.507924] usb 2-6: [Ueagle-atm] requesting firmware ueagle-atm/CMVep.bin.v2 failed, try to get older cmvs
[25.566055] usb 2-6: [ueagle-atm] modem started, waiting synchronization...
[36.576054] usb 2-6: [ueagle-atm] modem operational
`

Voilà. Je lance une bouteille à la mer.

bonne soirée  
dd

---

<div class="post-metadata">

**Author:** ![branch](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/ee7513/32.png) [@branch](https://www.debian-fr.org/u/branch)\
**Post date:** [Février 21, 2016, 11:43 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/3 "2016-02-21T11:43:14Z")

</div>

Salut,

[code]#!/bin/sh

modem\_debranche() {  
! lsusb | grep -qF ‘1110:900f’  
}

est\_le\_bon\_port() {  
nom\_port="${1}"  
[-f “${nom\_port}/idVendor”] &&  
[-f “${nom\_port}/idProduct”] &&  
[“$(cat “${nom\_port}/idVendor”)” = 1110] &&  
[“$(cat “${nom\_port}/idProduct”)” = 900f]  
}

reset\_port() {  
nom\_port="$1"  
echo 0 \> "/sys/bus/usb/devices/${nom\_port}/authorized"  
echo 1 \> “/sys/bus/usb/devices/${nom\_port}/authorized”  
}

modem\_pret\_pour\_pppd() {  
dmesg | grep -qF ‘[ueagle-atm] modem operational’  
}

if modem\_debranche; then  
exit 0  
fi

for port in /sys/bus/usb/devices/\* ; do  
if est\_le\_bon\_port “${port}”; then  
reset\_port "${port}"  
fi  
done

i=1  
while [“${i}” -le 60]; do  
sleep 1  
if modem\_pret\_pour\_pppd; then  
# lancer le modem avec pppd  
exit $?  
fi  
i="$(expr “${i}” + 1)"  
done

echo "erreur le modem n est toujours pas operationel au bout d une minute"  
exit 1  
[/code]

A noter qu’il peut y avoir plusieurs “ports” pour le même couple idVendor/idProduct (chez moi il y a usb1 et usb2). Donc je les déconnecte/reconnecte tous.

Si tu n’es pas habitué, l’option -q de la commande grep permet de renvoyer VRAI s’il y a au moins une occurence du motif qui est trouvée (et ça n’affiche rien).

De plus, lorsqu’on utilise pas le mot-clé return dans une fonction, la fonction renvoie la valeur de la dernière commande invoquée dans la fonction. Donc si la dernière commande d’une fonction est grep -q, et que grep -q renvoie VRAI, alors la fonction renvoie VRAI.

---

<div class="post-metadata">

**Author:** ![d2d2](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@d2d2](https://www.debian-fr.org/u/d2d2)\
**Post date:** [Février 21, 2016, 11:43 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/4 "2016-02-21T11:43:20Z")

</div>

Saut et merci !!

Je vien de tester en l’état ça ne fonctionnait pas :

`root@ordi:/home/sww/linux# sh ./reset_modem 
./reset_modem: 17: ./reset_modem: cannot create /sys/bus/usb/devices//sys/bus/usb/devices/2-6/authorized: Directory nonexistent
./reset_modem: 18: ./reset_modem: cannot create /sys/bus/usb/devices//sys/bus/usb/devices/2-6/authorized: Directory nonexistent
`

En modifiant les lignes 17 et 18,

` echo 0 > "${nom_port}/authorized"
  echo 1 > "${nom_port}/authorized"`

le script s’exécute bien, mais n’attend pas la fin du reset pour tester que le modem est opérationnel. Il faut un sleep quelque part ? :

[code]root@ordi:/home/sww/linux# sh -v ./reset\_modem  
#!/bin/sh

modem\_debranche() {  
! lsusb | grep -qF ‘1110:900f’  
}

est\_le\_bon\_port() {  
nom\_port="${1}"  
[-f “${nom\_port}/idVendor”] &&  
[-f “${nom\_port}/idProduct”] &&  
[“$(cat “${nom\_port}/idVendor”)” = 1110] &&  
[“$(cat “${nom\_port}/idProduct”)” = 900f]  
}

reset\_port() {  
nom\_port="$1"  
echo 0 \> "${nom\_port}/authorized"  
echo 1 \> “${nom\_port}/authorized”  
}

modem\_pret\_pour\_pppd() {  
dmesg | grep -qF ‘[ueagle-atm] modem operational’  
}

if modem\_debranche; then  
exit 0  
fi

for port in /sys/bus/usb/devices/\* ; do  
if est\_le\_bon\_port “${port}”; then  
reset\_port "${port}"  
fi  
done

i=1  
while [“${i}” -le 60]; do  
sleep 1  
if modem\_pret\_pour\_pppd; then  
# lancer le modem avec pppd  
exit $?  
fi  
i="$(expr “${i}” + 1)"  
done  
[/code]

---

<div class="post-metadata">

**Author:** ![d2d2](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@d2d2](https://www.debian-fr.org/u/d2d2)\
**Post date:** [Février 21, 2016, 11:43 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/5 "2016-02-21T11:43:28Z")

</div>

un petit tail -n dans le dmesg arrange tout.

Encore un très grand merci Branch ! Non seulement tu as résolu mon problème, mais j’aurais appris de nouvelles choses par l’exemple.

Comme je suis très (très) néophyte, j’ai lu que les fonctions devaient être précédée par fonction NOM et suivies de {}. Or, ici, on a NOM () {} … quelqu’un pourrait éclairer (même à la bougie) ma lanterne ?

Voici la version qui fonctionne pour ceux qui en auraient l’utilité comme moi, où qui voudraient tester :

[code]#!/bin/sh

#script pour reset du modem usb CT350 ID 1110:900f  
#greeting Branch

modem\_debranche() {  
! lsusb | grep -qF ‘1110:900f’  
}

est\_le\_bon\_port() {  
nom\_port="${1}"  
[-f “${nom\_port}/idVendor”] &&  
[-f “${nom\_port}/idProduct”] &&  
[“$(cat “${nom\_port}/idVendor”)” = 1110] &&  
[“$(cat “${nom\_port}/idProduct”)” = 900f]  
}

reset\_port() {  
nom\_port="$1"  
echo 0 \> "${nom\_port}/authorized"  
echo 1 \> “${nom\_port}/authorized”  
}

modem\_pret\_pour\_pppd() {  
dmesg | tail -n5 | grep -qF ‘[ueagle-atm] modem operational’  
}

if modem\_debranche; then  
exit 0  
fi

for port in /sys/bus/usb/devices/\* ; do  
if est\_le\_bon\_port “${port}”; then  
reset\_port "${port}"  
fi  
done

i=5  
while [“${i}” -le 60]; do  
sleep 1  
if modem\_pret\_pour\_pppd; then  
ppp-on  
exit $?  
fi  
i="$(expr “${i}” + 1)"  
done

echo "erreur le modem n est toujours pas operationel au bout d une minute"  
exit 1[/code]

---

<div class="post-metadata">

**Author:** ![branch](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/ee7513/32.png) [@branch](https://www.debian-fr.org/u/branch)\
**Post date:** [Février 21, 2016, 11:44 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/6 "2016-02-21T11:44:23Z")

</div>

Ce n’est pas normal qu’un tail -n5 règle le problème ![:confusion-scratchheadblue:](https://www.debian-fr.org/uploads/default/original/1X/7bbea83f89515ab7c7a738dddb86c4d4f140bd13.gif "Blue Scratching Head")

Il y a donc un problème caché non résolu. Tu peux tenter de le débusquer en remettant la version qui ne marche pas, et en remplaçant

` if modem_pret_pour_pppd; then
    ppp-on
    exit $?
  fi`

par

` if modem_pret_pour_pppd; then
    dmesg | tail
    ppp-on
    exit $?
  fi`

Normalement si la fonction modem\_pret\_pour\_pppd renvoie vrai, c’est qu’il y a la bonne ligne dans le dmesg ![:confusion-scratchheadblue:](https://www.debian-fr.org/uploads/default/original/1X/7bbea83f89515ab7c7a738dddb86c4d4f140bd13.gif "Blue Scratching Head")

J’ai une idée d’où peut provenir le problème : peut être que cette ligne ([ueagle-atm] modem operational) apparaît vers le début de ton dmesg. Peut-être que le modem est rendu fonctionnel au lancement de l’ordinateur. Du coup la fonction modem\_pret\_pour\_pppd renvoie toujours vrai. Si c’est bien ça le problème, une solution correcte pour le contourner est de calculer la taille (en nombre de lignes) du dmesg au moment du lancement du script, puis d’ignorer ensuite ces premières lignes dans la fonction modem\_pret\_pour\_pppd avec un tail. Voici le code complet que je propose (qui utilise des variables globales, normalement il faut toujours l’éviter, mais il est tard …) :

[code]#!/bin/sh

#script pour reset du modem usb CT350 ID 1110:900f

#variables globales : TAILLE\_DMESG\_INITIALE et NUMERO\_PREMIERE\_LIGNE\_NOUVELLE\_DU\_DMESG  
TAILLE\_DMESG\_INITIALE=«&nbsp;$(dmesg | wc -l)&nbsp;»  
NUMERO\_PREMIERE\_LIGNE\_NOUVELLE\_DU\_DMESG=«&nbsp;$(expr «&nbsp;${TAILLE\_DMESG\_INITIALE}&nbsp;» + 1)&nbsp;»

modem\_debranche() {  
! lsusb | grep -qF ‹&nbsp;1110:900f&nbsp;›  
}

est\_le\_bon\_port() {  
nom\_port=«&nbsp;${1}&nbsp;»  
[-f «&nbsp;${nom\_port}/idVendor&nbsp;»] &&  
[-f «&nbsp;${nom\_port}/idProduct&nbsp;»] &&  
[«&nbsp;$(cat «&nbsp;${nom\_port}/idVendor&nbsp;»)&nbsp;» = 1110] &&  
[«&nbsp;$(cat «&nbsp;${nom\_port}/idProduct&nbsp;»)&nbsp;» = 900f]  
}

reset\_port() {  
nom\_port=«&nbsp;$1&nbsp;»  
echo 0 \> «&nbsp;${nom\_port}/authorized&nbsp;»  
echo 1 \> «&nbsp;${nom\_port}/authorized&nbsp;»  
}

modem\_pret\_pour\_pppd() {  
dmesg | tail -n +«&nbsp;${NUMERO\_PREMIERE\_LIGNE\_NOUVELLE\_DU\_DMESG}&nbsp;» | grep -qF ‹&nbsp;[ueagle-atm] modem operational&nbsp;›  
}

if modem\_debranche; then  
exit 0  
fi

for port in /sys/bus/usb/devices/\* ; do  
if est\_le\_bon\_port «&nbsp;${port}&nbsp;»; then  
reset\_port «&nbsp;${port}&nbsp;»  
fi  
done

i=1  
while [«&nbsp;${i}&nbsp;» -le 60]; do  
sleep 1  
if modem\_pret\_pour\_pppd; then  
ppp-on  
exit $?  
fi  
i=«&nbsp;$(expr «&nbsp;${i}&nbsp;» + 1)&nbsp;»  
done

echo «&nbsp;erreur le modem n est toujours pas operationel au bout d une minute&nbsp;»  
exit 1

[/code]

* * *

Pour les fonctions, la syntaxe «&nbsp;normale&nbsp;» c’est celle que j’utilise. Je me réfère à la [spécification du shell POSIX publiée par l’opengroup](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05).

Le mot-clé function est spécifique au shell BASH. D’après la [spécification de BASH publiée par GNU](http://www.gnu.org/software/bash/manual/bash.html#Shell-Functions), ce mot-clé est optionnel en BASH.

Vu que tu as l’air de découvrir les fonctions en shell, je voudrais souligner deux points :

- si tu modifies une variable dans le corps de la fonction (par exemple la variable i), alors cette variable est modifiée partout, même en dehors de la fonction (et ça peut mettre le bazar si la variable i est utilisée en dehors de la fonction, par exemple pour contrôler une boucle while)

- lorsque tu appelles une fonction en lui passant des arguments (3 arguments par exemple), tu peux accéder à la valeur des arguments dans le corps de la fonction grâce aux variables spéciales $1, $2 et $3.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 11:44 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/7 "2016-02-21T11:44:24Z")

</div>

Il y a moyen de s’en protéger :

[code]#!/bin/sh

foo() {  
local i=2  
echo “foo = $i”  
}

bar() {  
i=4  
echo “bar = $i”  
}

i=1

echo "main = $i"  
foo  
echo "main = $i"  
bar  
echo “main = $i”[/code]  
Sortie :

`main = 1
foo = 2
main = 1
bar = 4
main = 4`  
Et donc :

`$ ll /bin/sh
lrwxrwxrwx 1 root root 4 18 mars 18:34 /bin/sh -> dash`

---

<div class="post-metadata">

**Author:** ![branch](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/ee7513/32.png) [@branch](https://www.debian-fr.org/u/branch)\
**Post date:** [Février 21, 2016, 11:44 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/8 "2016-02-21T11:44:25Z")

</div>

Exact, le fait de préfixer une déclaration de variable par le mot-clé local permet de rendre la modification de la variable locale à la fonction.

J’ai essayé avec le shell DASH, qui est censé n’implémenter que des fonctionnalités du shell POSIX, et ça fonctionne. Cependant, je ne trouve aucune trace de cette fonctionnalité dans la spécification POSIX publiée par l’OpenGroup (j’ai pas non plus cherché à fond).

---

<div class="post-metadata">

**Author:** ![d2d2](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/c4cdca/32.png) [@d2d2](https://www.debian-fr.org/u/d2d2)\
**Post date:** [Février 21, 2016, 11:44 UTC](https://www.debian-fr.org/t/script-au-demarrage/52850/9 "2016-02-21T11:44:42Z")

</div>

Salut et merci  
Effectivement, le modem est reconnu au lancement et apparaît donc dans dmesg ; mais, lorsque je lance mon sript de démarrage ppp-on, la connexion ne se fait pas, sauf si le modem est débranché-rebranché ou avec un reset.  
Je testerai ta version modifiée ce soir après le boulot.  
Enfin, merci pour les petites infos qui sont toujours intéressantes.
