Script au démarrage

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 :cry: alors merci d’avance pour votre aide :smiley:

dd

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

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 “modem operational” 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

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.

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]

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]

Ce n’est pas normal qu’un tail -n5 règle le problème :confusion-scratchheadblue:

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:

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="$(dmesg | wc -l)"
NUMERO_PREMIERE_LIGNE_NOUVELLE_DU_DMESG="$(expr “${TAILLE_DMESG_INITIALE}” + 1)"

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 -n +"${NUMERO_PREMIERE_LIGNE_NOUVELLE_DU_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
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]


Pour les fonctions, la syntaxe “normale” c’est celle que j’utilise. Je me réfère à la spécification du shell POSIX publiée par l’opengroup.

Le mot-clé function est spécifique au shell BASH. D’après la spécification de BASH publiée par GNU, 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.

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

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).

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.