Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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 wink) :

#!/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