• [^] # Re: ça avance :-)

    Posté par (site web personnel, Mastodon) . En réponse au message [résolu] visualiser charge CPU et mémoire | mesurer l'efficience. Évalué à 2.

    Arf, quand je disais que j'ai une écriture cryptique de dinosaure du shell

    Maintenant, il parait que je n'est pas la manière propre/canonique d'écrire les scripts : j'ai trop de vieux réflexes.

    Faut vraiment que je fasse gaffe quand je réponds sur les fora, pour ne pas embrouiller inutilement comme ici.

    # double pipe "||": si la commande existe on l'utilise sinon on ne tient pas compte du nbr de cœurs

    Ce n'est pas exactement ça, enfin ce n'est pas le sens du double pipe... Je m'explique par des exemple

    # enchainer sans condition
    ls -d ~/ ; echo "$? on y est"
    ls ~/notfound ; echo "$? suite"
    # echainer en cas de succès
    cd "$HOME" 2>/dev/null && echo "$? = maison"
    # echainer en cas d'échec
    cd /inexistant 2>/dev/null || echo "$? = perdu"
    # pseudo alternative
    cd ~/ && echo "ok" || echo "ko"
    cd /404 && echo "ok" || echo "ko"
    

    Ma syntaxe n'est pas conseillée en général parce-que si on ne la comprend pas on aura des effets de bord... Pour la partie en question, la syntaxe claire (pas besoin d'être gourou du shell pour comprendre) et sans effet de bord est

    if command -v nproc >/dev/null
    then
     NbrCrs=$(nproc --all)
    else
     NbrCrs=1
    fi

    Quand la commande existe, son chemin dans le PATH est renvoyé sur la sortie standard, raison pour laquelle je rajoute la redirection vers /dev/null pour ne pas polluer la version finale. En phase d'élaboration c'est utile pour s'assurer qu'on passe bien par là.


    Pendant que j'écris cette réponse je me rend compte qu'il y a une petite erreur que j'avais pas vu en lisant : ton premier appel à AWK n'a pas de fichier sur lequel travailler ...et n'est pas branché sur l'entrée standard par le pipe sur une autre commande. (c'est probablement à partir de là que ça part en vrille...)

    edit : je viens de relire, et j'avais laissé une erreur dans ma réponse.

    En relisant, je vois que j'avais pris soin de faire la transition

    echo -e "$TheTime\t$TheMem\t$TheLoad\t" >>"$outputfile"

    C'est juste les définition de variables juste avant qui ne collaient plus. Voici la correction que tu aurais du faire :

    TheMem=$(free -t | awk '/Mem:/{print 7ドル}')
    TheLoad=$(uptime | awk -v N=$NbrCrs '{print 10ドル/N}')
    TheTime=$(date +"%Y-%M-%dT%H%M%S")

    Mais bon, ça t'aurais permis de voir une des façon de déboguer du script shell : set -x va afficher tout ce qu'il fait avant de le faire, sorte de mode trace... Et aussi, souvent, pendant la phase de conception, on met des echo de vérification. Pour la version finale, quand c'est critique, on peut utiliser set -e qui fait planter (arrêter le script) quand une ligne est en erreur, au lieu de poursuivre en propageant des trucs incorrects. Tu peux aussi l'utiliser pour déboguer, par exemple dans le cas ci :

    set -e
    TheLoad=$(uptime | awk '{print 10ドル}') # load average de la dernière minute
    echo "2. $TheLoad"
    TheMem=$(awk -v N=$NbrCrs '/Mem:/ {print 7ドル/N}') # mémoire disponible
    echo "1. $TheMem"
    TheTime=$(date +"%Y-%M-%dT%H%M%S")
    echo "3. $TheTime"
    printf '%s\t' "$TheMem" >> $outputfile #
    cat "$outputfile"
    set +e
    exit

    (me semble que les affectations ne sont malheureusement pas en erreur, et puis les échos permettent aussi de savoir où on plante ...sauf si on a cumulé avec set -xe par exemple. c'est à toi de voir et d'adapter au cas par cas.)


    printf 'test hors bouuuucle\t'>> $outputfile # ✅

    Attention que echo termine par un retour à la ligne, et qu'il faut explicitement rajouter celui-ci pour printf qui te laisse gérer ton affichage.
    Mais c'est une bonne idée d'avoir les (noms des) champs sur la première ligne, histoire de savoir rapidement quoi est où sans devoir aller voir dans le code. Accessoirement, on note cette ligne comme un commentaire shell car beaucoup d'outils reconnaissent cela et sauteront la ligne (c'est le cas avec gnuplot) sinon on peut utiliser aussi des chaînes entrecôte (si le fichier est destiné uniquement aux tableurs)

    printf '#Timestamp\tFreeMemory\tAverageLoad' >> "$outputfile"

    Comme c'est la première action sur le fichier, tu peux utiliser > au lieu de >> et te passer du rm avant. (ou le remplacer par touch si tu tiens à changer la date de création.) :-)

    "It is seldom that liberty of any kind is lost all at once." ― David Hume