# Problème sur une boucle

**URL:** <https://www.debian-fr.org/t/probleme-sur-une-boucle/76329>\
**Category:** Programmation\
**Created:** [Avril 5, 2018, 7:14 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329 "2018-04-05T07:14:30Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 7:14 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/1 "2018-04-05T07:14:31Z")

</div>

Salut,

J’ai un petit souci sur une boucle dans un script bash … 😕

```auto
#!/bin/bash

cores="$(lscpu | grep -E 'Cœur|Coeur' | tr -s ' ' | tr -d ':' | sed 's/.* //')"
cores=$((cores-1))
cpus="$(lscpu | grep -E 'Socket|Support\(' | tr -s ' ' | sed 's/.* //')"
cpus=$((cpus-1))
sens="$(sensors | grep 'Core' | cut -d "(" -f 1 | cut -d "+" -f 2 | cut -c 1-4)"

echo "$sens"

echo "{"
echo "\"data\":["

comma=""
for cpu in $(seq 0 "$cpus")
do
        for core in $(seq 0 "$cores")
        do
                for temp in $sens
                do
                        echo " $comma{\"{#CPUID}\":\"$cpu\":\"{#COREID}\":\"$core\":\"{#TEMPID}\":\"$temp\"}"
                    comma=","
                done
        done
done

echo "]"
echo "}"

```

Techniquement la sortie devrait être du genre :

```auto
 
{
"data":[
    {"{#CPUID}":"0":"{#COREID}":"0":"{#TEMPID}":""}
    ,{"{#CPUID}":"0":"{#COREID}":"1":"{#TEMPID}":""}
    ,{"{#CPUID}":"0":"{#COREID}":"2":"{#TEMPID}":""}
    ,{"{#CPUID}":"0":"{#COREID}":"3":"{#TEMPID}":""}
    ,{"{#CPUID}":"0":"{#COREID}":"4":"{#TEMPID}":""}
    ,{"{#CPUID}":"0":"{#COREID}":"5":"{#TEMPID}":""}
    ,{"{#CPUID}":"1":"{#COREID}":"0":"{#TEMPID}":""}
    ,{"{#CPUID}":"1":"{#COREID}":"1":"{#TEMPID}":""}
    ,{"{#CPUID}":"1":"{#COREID}":"2":"{#TEMPID}":""}
    ,{"{#CPUID}":"1":"{#COREID}":"3":"{#TEMPID}":""}
    ,{"{#CPUID}":"1":"{#COREID}":"4":"{#TEMPID}":""}
    ,{"{#CPUID}":"1":"{#COREID}":"5":"{#TEMPID}":""}
]
}

```

La boucle sur laquelle je butte actuellement me permet de récupérer les températures par cores de chaque de chaque CPU (dans le cas de multi cpu.

Ayant trouvé le moyen d’exploiter la température des cores et non simplement des CPU sur l’ensemble du matériel hétérogène je me suis donc résigné à gérer les sondes de cette manière (c’est overkill mais ça marchera au moins 😛 ).

LA première boucle me permet de récupérer le nombre de socket physique, la seconde me permet de lui attribuer selon le nombre de core un numéro pour l’identifier.

la troisième boucle devrait pouvoir normalement lire un résultat et lui attribué une valeur à chaque ligne pour chaque core.  
Mais c’est la que le bas blesse, j’ai des erreurs sur chaques méthodes d’exploitations testé jusqu’alors 😣

Je récupère une liste de la sorte avec ma variable **$sens** :

```auto
69.0
69.0
68.0
69.0
67.0
65.0
55.0
51.0
52.0
48.0
51.0
52.0

```

Et donc je pensé faire une extraction lié au numéro de core +1 (car cela commence par zéro) afin de pouvoir dynamiquement utilisé ce type de script quelques soit le nombre de socket physique ou de cores par CPU.

Bien entendu je ne suis pas arrêté au BASH si vous avez une solution de remplacement à proposé en Perl ou en Python, mais je pense que le BASH sera plus simple à gérer.

---

<div class="post-metadata">

**Author:** ![PengouinPdt](https://www.debian-fr.org/user_avatar/www.debian-fr.org/pengouinpdt/32/3978_2.png) [@PengouinPdt](https://www.debian-fr.org/u/PengouinPdt)\
**Post date:** [Avril 5, 2018, 12:19 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/2 "2018-04-05T12:19:36Z")

</div>

Tu chercherais pas à faire du json, sans en avoir l’air ! 😛

Bon, j’allume ma Sid, histoire de voir 😉

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 12:30 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/3 "2018-04-05T12:30:47Z")

</div>

> [@PengouinPdt](#):
>
> Tu chercherais pas à faire du json, sans en avoir l’air ! 😛

Si si ,j’avoue 😛

---

<div class="post-metadata">

**Author:** ![Mimoza](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mimoza/32/3858_2.png) [@Mimoza](https://www.debian-fr.org/u/Mimoza)\
**Post date:** [Avril 5, 2018, 12:55 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/4 "2018-04-05T12:55:23Z")

</div>

> [@Clochette](#):
>
> j’ai des erreurs sur chaques méthodes d’exploitations testé

Attend je sort ma boule de cristale 🔮

J’ai testé ton script et … malheureusement il est inutilisable chez moi. Je dois avoir un CPU un peu trop ancien et il ne donne pas la température de chaque CPU.

Tu peux toujours mettre cette ligne en début de script pour faire du debug, tu verra ce qu’il se passe

> set -x

Mais dans la logique ça semble correcte.

---

<div class="post-metadata">

**Author:** ![Sputnik93](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/s/35a633/32.png) [@Sputnik93](https://www.debian-fr.org/u/Sputnik93)\
**Post date:** [Avril 5, 2018, 1:04 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/5 "2018-04-05T13:04:14Z")

</div>

Salut,

moi non plus je n’ai pas sensors d’installé, mais j’ai écrit en dur dans le script des valeurs comme indiqué par Clochette.  
Mais le problème est plutôt conceptuel d’après moi:  
dans $sens tu as toutes les valeurs relevées par sensors, donc pour tous les coeurs. Or, dans ta 2e boucle for, tu es normalement au niveau de chaque coeur d’un CPU donné, donc tu ne devrais pas reboucler un for sur toutes les valeurs de $sens.  
Parce que là ça donne ça:

```auto
sens: 69.0
52.0
cpus: 0
cores: 1
{
"data":[
    {"{#CPUID}":"0":"{#COREID}":"0":"{#TEMPID}":"69.0"}
    ,{"{#CPUID}":"0":"{#COREID}":"0":"{#TEMPID}":"52.0"}
    ,{"{#CPUID}":"0":"{#COREID}":"1":"{#TEMPID}":"69.0"}
    ,{"{#CPUID}":"0":"{#COREID}":"1":"{#TEMPID}":"52.0"}
]
}

```

Donc tu ne devrais pas faire le 3e for, mais plutôt chercher à indicer les valeurs de $sens pour récupérer la bonne une fois que tu es dans ta 2e boucle.

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 1:10 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/6 "2018-04-05T13:10:59Z")

</div>

Oh que oui, si jamais je laisse tel quel ça ne va pas et c’est justement pour le traitement finale de la température que je suis venu poster 😛

En gros cherche à conserver une boucle car le parc machine dispose de machine de 1 à 8 CPU et de 4 à 12 cores.

Du coup je cherche à exploiter une liste ‘verticale’ de valeur que j’attribue via une boucle **for** (tant qu’il y a des valeur en fin de compte) à chaque core renseigner par mes deux boucles précédentes.

Mais je conçoit que c’est tordu comme fonctionnement.

J’ai surtout besoin de générer une \*@#\>\<!$? de json avec les trois valeurs 😕

Mode verbeux attention les yeux 🙂

```auto
[root@cs-eu-fr-ikdc1-mysql01 scripts]# /etc/zabbix/scripts/discover_cores-V2.sh

cores="$(lscpu | grep -E 'Cœur|Coeur' | tr -s ' ' | tr -d ':' | sed 's/.* //')"
lscpu | grep -E 'Cœur|Coeur' | tr -s ' ' | tr -d ':' | sed 's/.* //')"
lscpu | grep -E 'Cœur|Coeur' | tr -s ' ' | tr -d ':' | sed 's/.* //')
lscpu | grep -E 'Cœur|Coeur' | tr -s ' ' | tr -d ':' | sed 's/.* //'
++ lscpu
++ grep -E 'Cœur|Coeur'
++ tr -s ' '
++ tr -d :
++ sed 's/.* //'
+ cores=6
cores=$((cores-1))
+ cores=5
cpus="$(lscpu | grep -E 'Socket|Support\(' | tr -s ' ' | sed 's/.* //')"
lscpu | grep -E 'Socket|Support\(' | tr -s ' ' | sed 's/.* //')"
lscpu | grep -E 'Socket|Support\(' | tr -s ' ' | sed 's/.* //')
lscpu | grep -E 'Socket|Support\(' | tr -s ' ' | sed 's/.* //'
++ lscpu
++ grep -E 'Socket|Support\('
++ tr -s ' '
++ sed 's/.* //'
+ cpus=2
cpus=$((cpus-1))
+ cpus=1
sens="$(sensors | grep 'Core' | cut -d "(" -f 1 | cut -d "+" -f 2 | cut -c 1-4)"
sensors | grep 'Core' | cut -d "(" -f 1 | cut -d "+" -f 2 | cut -c 1-4)"
sensors | grep 'Core' | cut -d "(" -f 1 | cut -d "+" -f 2 | cut -c 1-4)
sensors | grep 'Core' | cut -d "(" -f 1 | cut -d "+" -f 2 | cut -c 1-4
++ sensors
++ grep Core
++ cut -d '(' -f 1
++ cut -d + -f 2
++ cut -c 1-4
+ sens='67.0
69.0
67.0
69.0
66.0
66.0
54.0
50.0
51.0
49.0
53.0
53.0'

echo "$sens"
+ echo '67.0
69.0
67.0
69.0
66.0
66.0
54.0
50.0
51.0
49.0
53.0
53.0'
67.0
69.0
67.0
69.0
66.0
66.0
54.0
50.0
51.0
49.0
53.0
53.0

echo "{"
+ echo '{'
{
echo "\"data\":["
+ echo '"data":['
"data":[

comma=""
+ comma=
for cpu in $(seq 0 "$cpus")
do
        for core in $(seq 0 "$cores")
        do
               for temp in $sens
               do
                        echo " $comma{\"{#CPUID}\":\"$cpu\":\"{#COREID}\":\"$core\":\"{#TEMPID}\":\"$temp | head - "${$core+1}"\"}"
                    comma=","
               done
        done
done
seq 0 "$cpus")
seq 0 "$cpus"
++ seq 0 1
+ for cpu in '$(seq 0 "$cpus")'
seq 0 "$cores")
seq 0 "$cores"
++ seq 0 5
+ for core in '$(seq 0 "$cores")'
+ for temp in '$sens'
/etc/zabbix/scripts/discover_cores-V2.sh: line 23: " $comma{\"{#CPUID}\":\"$cpu\":\"{#COREID}\":\"$core\":\"{#TEMPID}\":\"$temp | head - "${$core+1}"\"}" : mauvaise substitution

echo "]"
+ echo ']'
]
echo "}"
+ echo '}'
}

```

---

<div class="post-metadata">

**Author:** ![Sputnik93](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/s/35a633/32.png) [@Sputnik93](https://www.debian-fr.org/u/Sputnik93)\
**Post date:** [Avril 5, 2018, 2:49 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/7 "2018-04-05T14:49:43Z")

</div>

Si tu veux afficher $core + 1, fais `$(($core + 1))` car `${core+1}` n’est pas correct.

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 2:54 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/8 "2018-04-05T14:54:46Z")

</div>

Lors d’un de mes derniers essais del a journée j’avais aussi tenté :

```auto
echo " $comma{\"{#CPUID}\":\"$cpu\":\"{#COREID}\":\"$core\":\"{#TEMPID}\":\"$($temp | head - "$(($core+1))")\"}"

```

Avec le mode debug je me rends bien compte que c’est mon head qui ne marche pas 😕

```auto
+ for temp in '$sens'
$temp | head - "$(($core+1))")\"}"
$temp | head - "$(($core+1))")"}
$temp | head - "$(($core+1))"
++ 50.0
++ head - 6
/etc/zabbix/scripts/discover_cores-V2.sh: line 23: 50.0 : commande introuvable
head: impossible d'ouvrir « 6 » en lecture: Aucun fichier ou dossier de ce type
+ echo ' ,{"{#CPUID}":"1":"{#COREID}":"5":"{#TEMPID}":"==> entrée standard <=="}'
    ,{"{#CPUID}":"1":"{#COREID}":"5":"{#TEMPID}":"==> entrée standard <=="}
+ comma=,

```

MAis j’avaoue ne plus trop comment réussir à lui faire prendre la valeur à la ligne équivalent à _$core + 1_

---

<div class="post-metadata">

**Author:** ![PengouinPdt](https://www.debian-fr.org/user_avatar/www.debian-fr.org/pengouinpdt/32/3978_2.png) [@PengouinPdt](https://www.debian-fr.org/u/PengouinPdt)\
**Post date:** [Avril 5, 2018, 2:59 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/9 "2018-04-05T14:59:50Z")

</div>

@Clochette, m’est avis que tu t’y prends mal 😉

un coup de man t’informerais de l’option -p \<= tu vas voir comment cela va te faciliter la vie 😉

```auto
lscpu -p | grep -v '#' | awk -F ',' '{ print "CPU: "$1"; Core: "$2 }'

```

(par exemple) 😉

ensuite ta commande sensors, tu peux drastiquement réduire ton code ainsi :

`sensors | awk '/Core/ { print susbstr($3, 2, 4) }'`

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 3:28 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/10 "2018-04-05T15:28:04Z")

</div>

> [@PengouinPdt](#):
>
> @Clochette, m’est avis que tu t’y prends mal 😉

J’en doute pas c’est un script vite fait mais qui doit être portable sur un maximum de machine.  
Je viens de jeter un oeil, effectivement la commande -p de lscpu facilité le traitement, mais mon véritable souci c’est de pouvoir après coup envoyer en valeur la ligne adéquat en fonction du core de façon à me fournir un json correctement exploitable après coup.

Je vais regarder pour rendre déjà le traitement plus sexy, mais je vois pas (même si c’est relativement laid ce que je fais 😛 ) pourquoi ça ne me traite pas mon head.

A croire que la valeur de $core disparait après traitement au lieu d’être conservée et modifée lors de la boucle d’après 🤔

---

<div class="post-metadata">

**Author:** ![PengouinPdt](https://www.debian-fr.org/user_avatar/www.debian-fr.org/pengouinpdt/32/3978_2.png) [@PengouinPdt](https://www.debian-fr.org/u/PengouinPdt)\
**Post date:** [Avril 5, 2018, 3:30 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/11 "2018-04-05T15:30:47Z")

</div>

> [@Clochette](#):
>
> J’en doute pas c’est un script vite fait mais qui doit être portable sur un maximum de machine.

C’est justement tout le soucis. Sur ma sid, ton écriture «&nbsp;Coeur&nbsp;» et son équivalent n’existe pas, il faut le restituer par son terme anglais.  
C’est pour cela que j’ai eu l’idée de regarder le man, me disant, au cas où qu’il faciliterait la vie avec une des options.  
Il en est sorti l’option ‹&nbsp;-p&nbsp;›… d’ailleurs, l’option ‹&nbsp;-J&nbsp;› est intéressante, mais te complexifiera le traitement…  
alors qu’avec ‹&nbsp;-p&nbsp;›, tu vas direct à l’essentiel ! 😉

---

<div class="post-metadata">

**Author:** ![Sputnik93](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/s/35a633/32.png) [@Sputnik93](https://www.debian-fr.org/u/Sputnik93)\
**Post date:** [Avril 5, 2018, 3:32 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/12 "2018-04-05T15:32:16Z")

</div>

Désolé, je persiste à penser qu’avec 2 for ce sera plus simple 😋

```auto
sens="temp1 temp2 ... tempN" # ou en liste verticale, c'est pareil
a=1
pour i=0 ; i <= $CPU ; i++
    pour j=0; j<=($Cores / $CPU) ; j++
        temp=$(echo $sens | cut -d ' ' -f $a) # température CPU i Core j
        a=a+1
    fin pour
fin pour

```

L’idée est de simplement parcourir la liste des coeurs, et pour chaque coeur récupérer l’indice de la variable $sens qui correspond, cet indice étant incrémenté à chaque nouveau coeur (dans la 2e boucle).

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 4:17 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/13 "2018-04-05T16:17:08Z")

</div>

Je vais regarder à ça dès que j’ai 5 minutes, merci déjà pour le temps passé à vous trois.

---

<div class="post-metadata">

**Author:** ![anon29980398](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/a/f4b2a3/32.png) [@anon29980398](https://www.debian-fr.org/u/anon29980398)\
**Post date:** [Avril 5, 2018, 7:25 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/14 "2018-04-05T19:25:32Z")

</div>

Bonsoir

si j’ai bien compris ce qu’il fallait,  
Je pensais juste à ça :

```bash
#!/bin/bash

indent=" "
sortie="{\n \"data\":[\n$indent"

while read; do
    if [["$REPLY" =~ "Physical id "([0-9]*) ]]; then
        cpu=${BASH_REMATCH[1]}
        read
        while [["$REPLY" =~ "Core "([0-9]*)": "*\+(.*)°C" " ]]; do
           sortie+=' {"{#CPUID}":"'$cpu'":"{#COREID}":"'${BASH_REMATCH[1]}'":"{#TEMPID}":"'${BASH_REMATCH[2]}'"},\n'"$indent"
           read
        done
    fi
done <<< "$(sensors)"

echo -e "${sortie%,*}\n$indent]\n}\n"

```

Qui pourrait donner une sortie de ce genre :

```nohighlight
{
 "data":[
          {"{#CPUID}":"0":"{#COREID}":"0":"{#TEMPID}":"37.0"},
          {"{#CPUID}":"0":"{#COREID}":"1":"{#TEMPID}":"37.0"},
          {"{#CPUID}":"0":"{#COREID}":"2":"{#TEMPID}":"31.0"},
          {"{#CPUID}":"0":"{#COREID}":"3":"{#TEMPID}":"27.0"},
          {"{#CPUID}":"1":"{#COREID}":"0":"{#TEMPID}":"35.0"},
          {"{#CPUID}":"1":"{#COREID}":"1":"{#TEMPID}":"39.0"},
          {"{#CPUID}":"1":"{#COREID}":"2":"{#TEMPID}":"34.0"},
          {"{#CPUID}":"1":"{#COREID}":"3":"{#TEMPID}":"26.0"}
        ]
}

```

---

<div class="post-metadata">

**Author:** ![Clochette](https://www.debian-fr.org/user_avatar/www.debian-fr.org/clochette/32/8757_2.png) [@Clochette](https://www.debian-fr.org/u/Clochette)\
**Post date:** [Avril 5, 2018, 9:21 UTC](https://www.debian-fr.org/t/probleme-sur-une-boucle/76329/15 "2018-04-05T21:21:55Z")

</div>

Alors la c’est exactement ça, et effectivement la solution de Sputnik93, m’avais amené a aussi un truc fonctionnel mais (et c’est surement lié à moi) beaucoup plus compliqué.

Merci à vous.
