#1 Le 27/04/2017, à 20:42
- migrec
Comportement non souhaité d'un script
Bonjour,
Je travaille sur un petit script pour calculer le temps qu'un utilisateur passe à utiliser son poste de travail (c'est totalement perso, histoire de me rendre compte du temps passé...).
En résumé, grâce à une boucle infinie et un sleep 3s à l'intérieur, le script s'exécute toutes les 3s et vérifie grace à xprintidle (qui sort le temps en ms depuis la dernière utilisation du clavier ou de la souris) que ce temps est inférieur à 1 minute. Ensuite :
- il écrit dans un fichier la date, l'heure de début de reprise, l'heure de fin, la durée et le cumul quotidien.
Pour être plus précis, j'ai voulu, lors de la mise en pause (donc forcement supérieur à 1 minute), enlever la valeur de xprintidle à l'heure de fin. Mais j'ai parfois un temps antérieur à l'heure de début et je ne comprend pas pourquoi ?
La section problématique du code est celle-ci :
function enPause {
# Mise à jour de la dernière ligne si le status précédent était en activité
if (! $IDLE) then
TEMPSECOULE="$(xprintidle)"
TEMPSPAUSE=$(($TEMPSECOULE / 1000))
HEUREREELLE="$(date +%T)"
HEUREFIN="$(date --date "$TEMPSPAUSE seconds ago" +%T)"
finActivite "$HEUREFIN"
echo ""
echo "L'ordinateur vient de se mettre en pause à $HEUREREELLE depuis $TEMPSECOULE ms soit $TEMPSPAUSE s."
echo "Adaptation de l'heure de fin d'activité avec $HEUREFIN..."
calculerDuree "$HEUREFIN"
calculerCumul
fi
IDLE=true
}
Ça produit parfois des lignes étonnantes. Ligne 3 et 7 : le 3ème champ contient l'heure de fin et il est inférieur à l'heure de début...
2017-04-26 07:25:41 07:34:11 00:08:30 00:08:30
2017-04-26 07:41:17 07:57:41 00:16:24 00:24:54
2017-04-26 08:00:01 07:59:59 00:25:49
2017-04-26 08:01:08 08:08:06 00:06:58 00:57:41
2017-04-26 08:09:29 08:15:45 00:06:16 01:03:57
2017-04-26 17:58:04 18:06:03 00:07:59 01:11:56
2017-04-26 18:08:04 18:08:03 01:12:54
2017-04-26 18:14:57 18:24:01 00:09:04 02:33:54
Avez-vous une idée de l'explication ?
Le script complet :
#!/bin/bash
# CAlcul du TEmps d'utIlisation CUmulé
# Répertoire d'enregistrement des fichiers journaliers
REPERTOIRE="/var/log/catecu"
# Nom initial du fichier
FICHIERDUJOUR="$(date +%F).log"
# Temps en ms depuis la dernière action utilisateur à partir duquel on considère que le poste est en pause
TEMPSIDLE="60000"
# Temps de bouclage
TEMPORISATION="3s"
# État initial (true = en pause, false = en activité)
IDLE=true
# Option future
FORMAT_DUREE="HMS"
#FORMAT_DUREE="S"
# Ajoute ou met à jour la dernière heure de début d'activité
function enActivite {
# echo "L'ordinateur a été utilisé récement." ;
HEURE="$(date +%T)"
# Si le statut précédent était "En pause", ajout d'une nouvelle ligne
# sinon, modification des champs de la dernière ligne.
if ($IDLE) ; then
DATE="$(date +%F)"
echo "$DATE $HEURE $HEURE 00:00:00 00:00:00" >> $FICHIERDUJOUR
else
finActivite "$HEURE"
calculerDuree "$HEURE"
fi
calculerCumul
IDLE=false
}
# Passe le statut en mode pause. On ne modifie pas les données sauf si le statut précedent était "En activité"
function enPause {
# Mise à jour de la dernière ligne si le status précédent était en activité
if (! $IDLE) then
TEMPSECOULE="$(xprintidle)"
TEMPSPAUSE=$(($TEMPSECOULE / 1000))
HEUREREELLE="$(date +%T)"
HEUREFIN="$(date --date "$TEMPSPAUSE seconds ago" +%T)"
finActivite "$HEUREFIN"
echo ""
echo "L'ordinateur vient de se mettre en pause à $HEUREREELLE depuis $TEMPSECOULE ms soit $TEMPSPAUSE s."
echo "Adaptation de l'heure de fin d'activité avec $HEUREFIN..."
calculerDuree "$HEUREFIN"
calculerCumul
fi
IDLE=true
}
# Modification de l'heure de fin d'activité (champ n°3) TODO : retrancher xprintidle car si la temporisation augmente, on a un décalage
function finActivite {
HEURE="$1"
sed -i -r '$s/(([^ ]+ ){2})([^ ]+( |$))(.*)/\1'"$HEURE"'\4\5/' $FICHIERDUJOUR
}
function calculerDuree {
HEUREFIN="$1"
HEUREDEBUT="$(awk 'END{print $2}' $FICHIERDUJOUR)"
DEBUT_S="$(date +%s --date="$HEUREDEBUT")"
FIN_S="$(date +%s --date="$HEUREFIN")"
DUREE_S="$(($FIN_S - $DEBUT_S))"
HEURES="$((DUREE_S / 3600))"
MINUTES="$((DUREE_S / 60 % 60))"
SECONDES="$((DUREE_S - (3600 * HEURES) - (60 * MINUTES)))"
DUREE_HMS="$(date +%T --date "$HEURES:$MINUTES:$SECONDES")"
sed -i -r '$s/(([^ ]+ ){3})([^ ]+( |$))(.*)/\1'"$DUREE_HMS"'\4\5/' $FICHIERDUJOUR
}
# Additionne toutes les durées du fichier en cours d'utilisation et ajoute ce total en remplacant le 5ème champ du fichier.
function calculerCumul {
# Calcul du temps total journalier
CUMUL_HMS="$(awk '{print $4}' $FICHIERDUJOUR | awk -F ':' '{T+=$1*3600+$2*60+$3} END {print strftime("%H:%M:%S",T,1)}')"
# Modification de la dernière ligne (5ème champ)
sed -i -r '$s/(([^ ]+ ){4})([^ ]+( |$))(.*)/\1'"$CUMUL_HMS"'\4\5/' $FICHIERDUJOUR
}
# Vérification que le fichier d'écriture est correct (date du jour)
# Si la période d'activitée est à cheval entre 2 journées, on met fin à l'activité
# de la journée précédente et on démarre une nouvelle activité à la date du jour
function verifierFichier {
DATE="$(date +%F)"
touch "$DATE.log"
if [ "$FICHIERDUJOUR" != "$DATE.log" ] ; then
echo "Changement de date :"
if ($IDLE) then
echo "Le poste était en pause donc le fichier de sortie ($FICHIERDUJOUR) est changé en $DATE.log."
FICHIERDUJOUR="$DATE.log"
else
echo "Le poste est en activité donc on cloture la journée précédente et on démarre un nouveau fichier..."
HEURE="23:59:59"
finActivite "$HEURE"
calculerDuree "$HEURE"
calculerCumul
FICHIERDUJOUR="$DATE.log"
echo "$DATE 00:00:00 00:00:00 00:00:00 00:00:00" >> $FICHIERDUJOUR
fi
fi
}
if (! test -d "$REPERTOIRE") then
mkdir "$REPERTOIRE"
fi
cd "$REPERTOIRE"
# Boucle principale
while (true) ; do
verifierFichier
TEMPSECOULE="$(/usr/bin/xprintidle)"
if (($TEMPSECOULE < $TEMPSIDLE)) ; then
enActivite
else
enPause
fi
sleep $TEMPORISATION
done
Hors ligne
#2 Le 01/05/2017, à 12:13
- Compte anonymisé
Re : Comportement non souhaité d'un script
Le code me paraissait inutilement compliqué, je te l'ai complètement réécrit (tes bugs devront pas réapparaître ) :
#!/bin/bash
TEMPSIDLE="60000"
TEMPORISATION="3"
date=$(date +%F)
debut=$(date +%T)
pause=0
while true
do
sleep $TEMPORISATION
if [ $(xprintidle) -lt $TEMPSIDLE ]&&[ "$pause" = 1 ]
then
pause=0
date=$(date +%F)
debut=$(date +%T)
#echo "reprise activité à $debut"
elif [ $(xprintidle) -gt $TEMPSIDLE ]&&[ "$pause" = 0 ]
then
pause=1
fin=$(date +%T)
#echo "fin activité $fin"
if [ "$date" == "$(date +%F)" ]
then
duree=$(($(date --date $fin +%s)-$(date --date $debut +%s)))
#echo "durée activité $(date -u --date @$duree +%T)"
dureetotal=$(($dureetotal+$duree))
echo "$date $debut $fin $duree $dureetotal" >> "$date.log"
else
dureejouravant=$(($(date --date $debut +%s)-$(date --date "23:59:59" +%s)))
duree=$(($dureejouravant+$(date --date $fin +%s)))
dureetotaljouravant=$(($dureetotal+$dureejouravant))
dureetotal=$(($dureetotal+$duree))
echo "$date $debut 23:59:59 $dureejouravant $dureetotaljouravant" >> "$date.log"
echo "$(date +%T) 00:00:00 $fin $duree $dureetotal" >> "$(date +%F).log"
fi
#echo "durée total activité $(date -u --date @$dureetotal +%T)"
fi
done
#3 Le 03/05/2017, à 21:49
- migrec
Re : Comportement non souhaité d'un script
Merci de t'être penché sur ce problème.
Je suis en train de tester ton script parallèlement au mien. Mais dans mon élan, j'ai été tenté de soustraire le temps d'inactivité à partir de l'heure de mise en pause détectée par le script et c'est ça qui me joue des tours je crois.
Je poursuis mes recherches ! Merci encore !
Hors ligne