OVH Cloud OVH Cloud

Interrompre une commande si elle dure plus de N secondes dans un script (bash a priori)

30 réponses
Avatar
Francois Lafont
Bonjour à tous,

J'explique un peu le contexte d'abord. J'ai un script local qui est
lancé à l'ouverture de session sur une Debian Squeeze et dans ce script
local il y a ça :

#-------------------------------------------
if [ -r "/mnt/script_distant" ]; then
/bin/bash "/mnt/script_distant"
fi
#-------------------------------------------

Je teste si le fichier script_distant est bien accessible en lecture car
en réalité /mnt est un répertoire sur lequel est monté un partage Samba
et il se peut que le serveur Samba soit (momentanément) en carafe et
donc, bien que le montage ait été effectué correctement auparavant, le
fichier script_distant peut être (momentanément) inaccessible.

Mon problème, c'est que ce test dure vraiment longtemps dans le cas où
justement le serveur est en carafe (ça peut prendre une vingtaine de
secondes parfois) ce qui ralentit beaucoup trop l'ouverture de session.
Ce que je voudrais, du coup, c'est interrompre le test s'il dure plus de
5 secondes (par exemple), sachant qu'au delà de cette limite 5 secondes,
je décide que c'est mort pour le lancement du script_distant et le
script local passe à la suite de son travail.

Donc ma question est : comment faire pour interrompre une commande si
elle dure plus de 5 secondes ?

En faisant des recherches sur le Web, je suis arrivé à ça :

#-------------------------------------------
# Exemple fictif de commande qui peut durer...
sleep 10 &

compteur=$((1))

COMMANDE_INTERROMPUE=false

# On teste si le processus est en cours
# avec la valeur de retour de « ps $! ».

while ps $! >/dev/null 2>&1; do

if [ $compteur -le 5 ]; then
sleep 1
compteur=$((compteur+1))
else
kill -SIGKILL $! >/dev/null 2>&1
COMMANDE_INTERROMPUE=true
#break
fi

done

if $COMMANDE_INTERROMPUE; then
echo "La commande a été interrompue"
else
echo "La commande n'a pas été interrompue"
fi
#-------------------------------------------

1) Est-ce correct d'après vous ? Toute remarque constructive est la
bienvenue. ;-)

2) Je me pose une question à propos du « break » que j'ai laissé en
commentaire ci-dessus. En l'état, si je lance ce script (il s'appelle
test.bash), j'ai :

#-------------------------------------------
$ bash test.bash
test.bash: line 22: 10160 Processus arrêté sleep 10
La commande a été interrompue
#-------------------------------------------

Je n'arrive pas à comprendre pourquoi j'ai la sortie « test.bash: line
22: 10160 Processus arrêté sleep 10 » ? Elle provient de la sortie
standard des erreurs du script test.bash lui-même, c'est donc une erreur
dans le script, mais je ne la comprends pas. En revanche, si je «
décommente » le break, alors :

#-------------------------------------------
$ bash test.bash
La commande a été interrompue
#-------------------------------------------

Je n'ai plus cette erreur. Avez-vous une explication ?

Merci d'avance pour votre aide.


--
François Lafont

10 réponses

1 2 3
Avatar
Francois Lafont
Le 07/03/2012 22:10, Luc Habert a écrit :
Francois Lafont :

Y a-t-il une réelle différence au final entre les 3 instructions
ci-dessous ?

1) c=1
2) c="1"



Ces deux-là ne diffèrent qu'au niveau du lexing, l'arbre syntaxique
pondu doit être identique.

3) c=$((1))



Là, ça va donner le même résultat sur ce cas particulier, mais l'arbre
syntaxique (et l'exécution qui en découle sauf optimisation à la noix) est
vraiment différent : ton 1 est converti en nombre, ce nombre devient
immédiatement le résultat de l'expression, et est reconverti en string à la
fin. Tu peux voir la différence avec « $((01)) », ça donne « 1 ».



Ok, mais donc dans les trois cas, on obtient bien une variable « de type
chaîne de caractères » (je ne sais pas si c'est une terminologie correct
en bash) ?

Je crois avoir lu quelque part qu'en shell bourne, toute variable était
en fait une chaîne de caractère. Comme bash possède quelques compétences
en arithmétique (que ne possède pas le bourne shell, je crois), je me
demandais si entre :

c=$((1))
c="1"

l'une était de type chaîne de caractères et l'autre de type entier ? Ce
n'est pas le cas ? Il n'y a qu'un seul type aussi en bash ?


--
François Lafont
Avatar
Francois Lafont
Le 07/03/2012 22:22, Fabien LE LEZ a écrit :

À défaut de gratuit, tu peux essayer Astraweb :
http://www.news.astraweb.com/plans.html

Il ont une offre "25 Go pour $10". Si tu ne télécharges pas de
binaires, les 25 Go devrait te suffire pour un paquet d'années.



Ah oui, en effet 25 Go de message en format texte, ça laisse le temps.

Cela dit, la panne de ce week-end est la première depuis très
longtemps. Le serveur news.free.fr est, d'une manière générale, très
stable.



C'est vrai, mais par exemple je viens de m'apercevoir (via Google Group)
qu'en ce moment même il y a des messages sur
fr.comp.os.linux.configuration datant sur 5 qui ne sont toujours pas
descendu sur mon lecteur de news et je me demande d'ailleurs s'ils
viendront un jour. Que ça bloque de temps en temps (rarement c'est vrai)
ok, mais louper des messages ça me gêne un peu quand même.

--
François Lafont
Avatar
Nicolas George
Fabien LE LEZ , dans le message
, a écrit :
Cela dit, la panne de ce week-end est la première depuis très
longtemps. Le serveur news.free.fr est, d'une manière générale, très
stable.



Euh, la panne « de ce week-end », elle durait depuis plus de trois mois.

(La connexion au serveur retournait EHOSTUNREACH sans raison apparente
environ une fois sur trois, de manière indépendante du round-robin DNS.)
Avatar
Arnaud Gomes-do-Vale
Francois Lafont writes:

C'est vrai, mais par exemple je viens de m'apercevoir (via Google Group)
qu'en ce moment même il y a des messages sur
fr.comp.os.linux.configuration datant sur 5 qui ne sont toujours pas
descendu sur mon lecteur de news et je me demande d'ailleurs s'ils
viendront un jour. Que ça bloque de temps en temps (rarement c'est vrai)
ok, mais louper des messages ça me gêne un peu quand même.



Installe ton serveur à toi chez toi, c'est ça qui marche le mieux. :-)

--
Arnaud
http://blogs.glou.org/arnaud/
Avatar
Francois Lafont
Le 07/03/2012 23:44, Arnaud Gomes-do-Vale a écrit :
Francois Lafont writes:

C'est vrai, mais par exemple je viens de m'apercevoir (via Google Group)
qu'en ce moment même il y a des messages sur
fr.comp.os.linux.configuration datant sur 5 qui ne sont toujours pas
descendu sur mon lecteur de news et je me demande d'ailleurs s'ils
viendront un jour. Que ça bloque de temps en temps (rarement c'est vrai)
ok, mais louper des messages ça me gêne un peu quand même.



Installe ton serveur à toi chez toi, c'est ça qui marche le mieux. :-)



Heu, mais un mon serveur à moi, il faudra bien qu'il aille cherche les
messages... sur un serveur de news « public », non ?


--
François Lafont
Avatar
Tonton Th
On 03/07/2012 11:48 PM, Francois Lafont wrote:

Heu, mais un mon serveur à moi, il faudra bien qu'il aille cherche les
messages... sur un serveur de news « public », non ?



Tout est expliqué là :
http://usenet-fr.chainon-marquant.org/Accueil

suite dans fr.usenet.divers

--

Nous vivons dans un monde étrange/
http://foo.bar.quux.over-blog.com/
Avatar
Doug713705
Le 07-03-2012, Francois Lafont nous expliquait dans
fr.comp.os.linux.configuration :

(Si vous connaissez un autre serveur de news
gratuit etc., ça m'intéresse.)



Ben le mien, si tu veux un compte envoie moi un mail (mon from et mon
reply-to sont valides).

Ce serveur est gratuit, sans limitation et propose la totalité du
usenet mondial sauf les binaires.

--
Doug - Linux user #307925 - Slackware64 roulaize ;-)
http://usenet-fr.chainon-marquant.org
http://newsportal.chainon-marquant.org
http://news.chainon-marquant.org
Avatar
Benoit Izac
Bonjour,

le 07/03/2012 à 22:25, Francois Lafont a écrit dans le message
<4f57d233$0$16670$ :

Ok, mais donc dans les trois cas, on obtient bien une variable « de type
chaîne de caractères » (je ne sais pas si c'est une terminologie correct
en bash) ?

Je crois avoir lu quelque part qu'en shell bourne, toute variable était
en fait une chaîne de caractère. Comme bash possède quelques compétences
en arithmétique (que ne possède pas le bourne shell, je crois), je me
demandais si entre :

c=$((1))
c="1"

l'une était de type chaîne de caractères et l'autre de type entier ? Ce
n'est pas le cas ? Il n'y a qu'un seul type aussi en bash ?



En shell, il n'y a pas de typage (pas de « int », « char », « string »,
etc.) ; une variable stocke une chaîne de caractère. Ce que voulait
souligner Luc, c'est ce qui explique le comportement du programme
suivant :

#!/bin/sh
v1=1
v2="1"
v3=$((1))
test "$v1" = "$v2" && echo "v1 = v2"
test "$v2" = "$v3" && echo "v2 = v3"
test "$v3" = "$v1" && echo "v3 = v1"
t1
t2="01"
t3=$((01))
test "$t1" = "$t2" && echo "t1 = t2"
test "$t2" = "$t3" && echo "t2 = t3"
test "$t3" = "$t1" && echo "t3 = t1"
exit 0

Dans le premier cas, c'est purement équivalent (d'où ma remarque), dans
le second, « $(()) » fait que le résultat diffère : t3 contient « 1 »,
les autres « 01 ».

--
Benoit Izac
Avatar
Francois Lafont
Bonsoir,

Le 08/03/2012 21:32, Benoit Izac a écrit :

Je crois avoir lu quelque part qu'en shell bourne, toute variable était
en fait une chaîne de caractère. Comme bash possède quelques compétences
en arithmétique (que ne possède pas le bourne shell, je crois), je me
demandais si entre :

c=$((1))
c="1"

l'une était de type chaîne de caractères et l'autre de type entier ? Ce
n'est pas le cas ? Il n'y a qu'un seul type aussi en bash ?



En shell, il n'y a pas de typage (pas de « int », « char », « string »,
etc.) ; une variable stocke une chaîne de caractère.



Ok, c'est vraiment sur ce point là que j'avais un doute concernant le
shell Bash (pas le shell Bourne). Mais c'est très clair. Le $(()) permet
une évaluation arithmétique mais au bout du compte, on obtient toujours
une chaîne de caractère.

C'est qu'en tombant sur deux trois trucs dans le man bash, j'avais
vraiment un doute qui s'était installé. Par exemple quand j'étais tombé
sur le built-in typeset avec l'option -i. Je cite :

« -i The variable is treated as an integer; arithmetic evaluation (see
ARITHMETIC EVALUATION above) is performed when the variable is assigned
a value. »

Ce qui permet des trucs comme :

$ typeset -i a
$ a=2
$ a=$a+5
$ echo $a
7

Il y avait de quoi mettre le doute je trouve. Mais maintenant, je
comprends que « typeset -i a » est une façon de dire au bash : à chaque
fois que tu auras « a=xxx » tu interpréteras « a=$((xxx)) » et au final
a stocke toujours une chaîne de caractères.

Ce que voulait
souligner Luc, c'est ce qui explique le comportement du programme
suivant :

#!/bin/sh
v1=1
v2="1"
v3=$((1))
test "$v1" = "$v2" && echo "v1 = v2"
test "$v2" = "$v3" && echo "v2 = v3"
test "$v3" = "$v1" && echo "v3 = v1"
t1
t2="01"
t3=$((01))
test "$t1" = "$t2" && echo "t1 = t2"
test "$t2" = "$t3" && echo "t2 = t3"
test "$t3" = "$t1" && echo "t3 = t1"
exit 0

Dans le premier cas, c'est purement équivalent (d'où ma remarque),



Ok.

dans
le second, « $(()) » fait que le résultat diffère : t3 contient « 1 »,
les autres « 01 ».



C'est parfaitement clair.
Merci beaucoup Benoît.

À+


--
François Lafont
Avatar
Tonton Th
On 03/08/2012 09:32 PM, Benoit Izac wrote:
Je crois avoir lu quelque part qu'en shell bourne, toute variable était
en fait une chaîne de caractère. Comme bash possède quelques compétences
en arithmétique (que ne possède pas le bourne shell, je crois), je me
demandais si entre :

c=$((1))
c="1"

l'une était de type chaîne de caractères et l'autre de type entier ? Ce
n'est pas le cas ? Il n'y a qu'un seul type aussi en bash ?



En shell, il n'y a pas de typage (pas de « int », « char », « string »,
etc.) ; une variable stocke une chaîne de caractère. Ce que voulait



En Bash (et en Ksh, probablement aussi), il y a quand même
des possibilités :

:/tmp$ help declare
declare: declare [-aAfFilrtux] [-p] [name[=value] ...]
Set variable values and attributes.

Declare variables and give them attributes. If no NAMEs are given,
display the attributes and values of all variables.

[...]

-i to make NAMEs have the `integer' attribute


[...]




--

Nous vivons dans un monde étrange/
http://foo.bar.quux.over-blog.com/
1 2 3