Problème de script bash

Tags: #<Tag:0x00007f63f4e680e8> #<Tag:0x00007f63f4e7ff90>

Bonjour,
J’ai un problème avec un script bash, qui fonctionne apparemment en console, mais pas en tache cron.
Quand je mets “set -xve” je n’ai pas de message d’erreur (en console).
[ le script récupère la température carte mère et processeur et les envois sur un afficheur usb]

Quand j’utilise le script dans une tache cron, voila les messages d’erreurs remontés:

/home/containers/sitronix/affichage_temperature.sh: ligne 32 : [: -ge : opérateur unaire attendu
/home/containers/sitronix/affichage_temperature.sh: ligne 35 : [: -lt : opérateur unaire attendu

(je sais ce que vous allez dire: un exécutable dans ce répertoire, c’est pas top, mais c’est pour évaluer la faisabilité). Avec cron, j’ai bien une image, mais avec l’heure, Zero, et la température carte mère (cf tout en bas).

Le script:

!#/bin/env /bin/bash
# set -xve
#-----------------------------------------------------
# affichage de la temperature sur écran d'un petit
# appareil 'digital photo frame'
# hack sous linux ici:
# http://neophob.com/2009/01/photo-frame-hack-updated-libst2205/
#-----------------------------------------------------
#
# on envoi la température au script et il l'affiche sur le péripherique
# R. Suinot <remi@suinot.org>
# 08 juillet 2011
# Dépendances: imagemagick
#              st2205tools
#              libgd2-xpm-dev (pour compiler st2205tools) sauf si libst2205 utilise.
#              digitemp
#-----------------------------------------------------

# convert -bordercolor green -border 5 -background lightblue -fill red  -size 90x90  -pointsize 30  label:"+24°C" label.png

# Temperature=`/usr/bin/digitemp_DS2490 -t 0 -q -c /etc/digitemprc -o%.0C`
cd /home/containers/sitronix
Temperature=`cat /tmp/Core-0.txt `
Carte_Mere=`cat /tmp/Temp3.txt `
Texte0=`echo $Temperature | awk -F '[\+\.]' '{ print $2 }'`
Tmp="/tmp/label.txt"
Image="/tmp/label.png"
expr $Texte0 + 0 1>/dev/null 2>&1
  if [ $? -eq 0 -o $? -eq 1 ]; then
    if [ $Texte0 -ge 1 ]; then
      # supérieur ou égal à 1
      Texte0="+"$Texte0"°C"
    elif [ $Texte0 -lt 0 ]; then
      # inférieur à zéro
      Texte0="-"$Texte0"°C"
    else
      # alors $Texte0 egale zéro
      Texte0="Zéro"
    fi
  else
    echo "*** non numerique"
    return
  fi
echo " \n" > $Tmp
echo $Texte0 >> $Tmp

# Arrivé ici, on continu pour la température carte mère

Texte1=`echo $Carte_Mere | awk -F '[\+\.]' '{ print $2 }'`
expr $Texte1 + 0 1>/dev/null 2>&1
  if [ $? -eq 0 -o $? -eq 1 ]; then
    if [ $Texte1 -ge 1 ]; then
      # supérieur ou égal à 1
      Texte1="+"$Texte1"°C"
    elif [ $Texte1 -lt 0 ]; then
      # inférieur à zéro
      Texte1="-"$Texte1"°C"
    else
      # alors $Texte1 egale zéro
      Texte1="Zéro"
    fi
  else
    echo "*** non numerique"
    return
  fi
echo $Texte1 >> $Tmp

h=`date +%k"h"%M`
# Définition des options pour le programme convert:
Texte=$h"\n"$Texte0"\n"$Texte1
echo $Texte > $Tmp
Border=2
BorderColor="green"
Backgr="lightblue"
TextColor="Red"
SizeEcran="90x90"
SizeText=17
Gravity="North"

convert -bordercolor $BorderColor -border $Border -background $Backgr -fill $TextColor -size $SizeEcran -pointsize $SizeText -gravity $Gravity label:$Texte $Image

# recherche de l'afficheur dans /dev
Device="/dev/"`ls -l /dev/disk/by-id/ | grep SITRONIX | awk '{print substr( $0, length($0) - 2, length($0))}'`
if [ -n $Device ]; then
  cp $Tmp "$PWD/"
  cp $Image "$PWD/"

# envoi de l'image à l'afficheur
  /usr/local/bin/setpic $Device $Image >/dev/null 2>&1
fi

Le contenu des fichiers:

$ cat /tmp/Core-0.txt
+48.0°C
$ cat /tmp/Temp3.txt
+29.0°C

Le résultat au travers de cron:

$ cat /tmp/label.txt 
 11h30\nZéro\n+28°C

Pareil, mais en console:

$ cat /tmp/label.txt
11h41\n+48°C\n+28°C

J’avoue ne pas comprendre d’ou vient le problème!!!
Si vous pouviez m’éclairer de vous lumières, je vous en serais éternellement reconnaissant.

Rémi.

Essaie de remplacer les[ ] par des[[ ]]

À la première ligne de ton script tu as écrit :
!#/bin/env /bin/bash
au lieu de :
#!/bin/env /bin/bash

C’est possible qu’à cause de cette erreur il soit exécuté avec sh (dash sur Debian) au lieu de bash.

@anon96191775 non le !# est une erreur de recopie, désole.(avant de faire un copié collé pour le reste)
@manuvu: je teste. Réponse dans 1/2 heure…

Merci de vos avis

Sinon il te reste à explorer les logs (messages et syslog).

Sinon, la méthode du pauvre que j’applique ne ce moment sur du script perl long comme ma b…, créer toi même un fichier de log avec du echo (vue que c’est du bash) entre chaque phase de ton script pour voir ou ça bloque.

Assure toi aussi que ta crontab ne cherche pas à le lancer malgré tout avec Dash en lui précisant directement bash comme shell comme ceci :

** * * * bash /path_de_ton_script.sh

Alors: résultats négatifs.

home/containers/sitronix/affichage_temperature.sh: ligne 31: erreur de syntaxe dans une expression conditionnelle
 /home/containers/sitronix/affichage_temperature.sh: ligne 31: erreur de syntaxe près de « -o »
/home/containers/sitronix/affichage_temperature.sh: ligne 31: ` if [[ $? -eq 0 -o $? -eq 1 ]]; then'

Je crois que je vais effectivement me faire un fichier de log “perso”. D’autant plus qu’il n’y a rien dans syslog , rien de plus que les mails de crin.

Je vous remonterai ce que je trouve.
Mais pas ce soir

La suite:
La bonne nouvelle, c’est que mon script fonctionne.
La mauvaise, c’est que de temps en temps, la valeur dans $Temperature ou dans $Carte_Mere est à "rien"
Les deux fichiers core-0.txt et Temp3.txt sont bien présent, en lecture, et actualisés.
La question que je me pose:
Si la création des deux fichiers et l’exécution de mon script sont dans deux taches cron différentes mais executés en même temps (typiquement 0h00, 0h30, …), est il possible que mon script puisse être en lecture sur un des deux alors qu’il est en cours de réécriture?

Actuellement, j’ai contourné le problème, je remonte mes températures directement par la lecture de sensors:

# Temperature=`cat /tmp/Core-0.txt `
Temperature=$(sensors | grep "Core 0:" | awk '{print $3}')
# Carte_Mere=`cat /tmp/Temp3.txt `
Carte_Mere=$(sensors | grep "temp3" | awk '{print $2}')

Et cela à l’air de fonctionner!
Merci de vos avis.

Bonjour.
Je reviens sur mon problème, en partie résolu (d’ailleurs, je ne l’avais pas mis en résolu)
Pour mon soucis premier, cela fonctionne, mais j’ai une remontée d’erreur de cron tous les jours, de 23h00 à 9h30, et toutes les demi-heure ( la crontab est toutes les 1/2h) c’est précis, mais systématiquement dans cet intervalle.

convert: unable to open image `9h00\n+59°C\n+37°C': Aucun fichier ou dossier de ce type @ error/blob.c/OpenBlob/2701.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/504.
convert: no images defined `/tmp/label.png' @ error/convert.c/ConvertImageCommand/3258.

À priori, je dirais qu’il n’atteint pas mon fichier dans /tmp et pourtant, il y est. Si j’execute le script manuellement dans la période où j’ai l’erreur de crontab, il fonctionne parfaitement pourtant.
À votre avis, c’est un problème de cron?

Tu pourrais sans doute tenter d’utiliser l’outil timer de systemd (si systemd est en place sur le serveur) et faire un tests de présence et d’accès au fichiers en question à l’aide d’une boucle d’essai.

En exemple :

# On regarde si Apache 2 est déja installé
$result = checkProcess($checkProcess);

# Si on a pas de résultat on tente l'installation
if($result != 0)
{
	# On va checker si il est installé
	while($is_validate == 0 && $try_count < $try_count_max)
	{
		# On affiche un message pour les tentatives
		&say("Tentative ".$try_count."/".$try_count_max." d'installation d'Apache 2");

BLA BLA BLA ...

	# Cas il n'est pas installé
	if($try_count == $try_count_max)
	{
		$retour = 2;
	}
}
else
{
	&say("Apache 2 est deja installe sur le serveur.");
	$retour = 1;

Le principe de ce type de boucle étant de gérer un compteur avec un test sur une ou plusieurs conditions et de faire une sortie propre en cas d’erreur pouvant amener à un envoi de mail pourquoi pas.

Cela permettra de pouvoir t’assurer que le script si il rencontre une erreur puisse à l’aide d’un echo te signaler ce qu’il l’a bloqué en particulier.

Ce type de boucle While devrait se mettre ne place à moindre coût sur chaque, l’autre solution serait de mettre une rotation de log sur un simple fichier text et de le lire pour remonter la température, tu pourra ainsi te permettre de du debug.

-> on peu imaginer faire du echo avec un @ en début de ligne pour te faire du debug, un echo à chaque étape pour te permettre de suivre au plus juste le déroulement de ton script, tu pourra parser les températures de ton fichier en éliminant les @.

C’est archaïque mais te permettra de pouvoir faire une sorte de mode debug, mais je soupçonne une non remontée d’information ne permettant pas de générer ton image

Sinon question toute bête la machine ne gère pas une sorte de mise ne veille hardware par fois ?

@Clochette :
Désolé du retard de la réponse.
Je ne connais pas l’outil timer de systemd.
Je vais chercher par la.

Merci pour la suggestion.