PROJET AUTOBLOG


Planet-Libre

source: Planet-Libre

⇐ retour index

Thuban : Publication d'isotop-0.2.1

lundi 30 octobre 2017 à 11:11

Première mise à jour pour isotop, l'OpenBSD personnalisée et préparée pour une utilisation bureau.

Parmi les changements effectués, vous remarquerez que :

Tous les liens sont sur la page officielle, je recopie ici uniquement les magnets à ouvrir avec un client bittorrent (avec trackers publics)

magnet:?xt=urn:btih:45e36d480c6e813e822fbd36f454799a0bde686d&dn=isotop-0.2.1-amd64-full.fs.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:8d86b6c82bec186da5ce800c6497ec04d9d42f59&dn=isotop-0.2.1-amd64-full.iso.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:6523d3c7a9923ec0b78d12501afffe05c6960e95&dn=isotop-0.2.1-amd64-netinst.fs.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:81d3582a2988699746ea896b96b2a596d99ddb08&dn=isotop-0.2.1-amd64-netinst.iso.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:42f765c3d53ee04b2a85b694fa9b0a5994885d91&dn=isotop-0.2.1-i386-full.fs.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:f28fad02eb0bcf4d155930f6374243674c857418&dn=isotop-0.2.1-i386-full.iso.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:27c53186b29bd785ebbf6ff48563191f2a2014a9&dn=isotop-0.2.1-i386-netinst.fs.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

magnet:?xt=urn:btih:fc9fc6b8f57cf9773071eb8deda187eb59cdbd8d&dn=isotop-0.2.1-i386-netinst.iso.xz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=http%3A%2F%2Fopensharing.org%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337

Pour finir, je laisse ici une petite vidéo d'une installation filmée, en 15 minutes 34 secondes chrono, pour fred' ;)

Gravatar de Thuban
Original post of Thuban.Votez pour ce billet sur Planet Libre.

Max Koder : Exploiter du JSON en Bash avec PHP

lundi 30 octobre 2017 à 10:34
Du JSON en Bash avec PHP

Faire du JSON avec PHP ou tout autre langage orienté web, c’est trivial. Mais lorsqu’il faut commencer à se le coltiner en Bash, c’est déjà plus galère..
Pour un besoin personnel, je dois justement lire du JSON dans un shell. Le cahier des charges est simple : J’ai PHP et Python sur la bécane (un serveur), et dans l’optique de partager ce code plus tard, je ne souhaite pas avoir de dépendances. Exit donc jq, qui est une librairie permettant de combler largement mon besoin. En plus, je ne connais pas grand chose à Python, et j’ai franchement pas le temps de m’y mettre.
Dans ce billet, je vous montre comment exploiter du JSON en Bash avec PHP. Je tiens tout de même à préciser que cet article n’a pas vocation à vous apprendre ces 2 langages, mais suppose que vous en connaissiez déjà les bases.

Je vous préviens, c’est long, mais c’est également l’occasion de voir quelques astuces Bash (notamment sur les tableaux) que peut-être vous ne connaissiez pas

Petit aparté

J’avais dit vouloir prendre un peu de recul par rapport à ce blog, et me recentrer. Je continue donc le site dont je vous avais parlé, mais il est difficile pour moi de ne pas écrire ici dès lors que j’ai le clavier sous la main, dès que quelque chose me trotte dans la tête.
Aujourd’hui, reprise du boulot, je lâche ma tasse de café pour rédiger quelques lignes ici. On ne se refait pas. Et puis, je ne m’étais jamais imposé de rythme, alors autant continuer comme ça.
Oui, je change d’avis comme de chemise. Ou plutôt, je fais comme bon me semble, comme j’ai toujours fait. Si demain je n’ai pas envie de continuer cet article, qui ira me dire quelque chose ?

Je crois que je ne sais pas comment évoluera mon temps passé sur le PC. Il y a fort à parier qu’à terme les extras ne se fassent plus. Je consultais de temps à autre Mastodon, mais il ne s’agit pour la plupart que de geeks / libristes qui exposent leurs articles, des liens vers un tweet, une humeur à partager. Je n’ai pas besoin de ça.
Au contraire, je pense qu’en fait ce blog est devenu le centre de mon activité sur Internet, et que le reste ne fait que graviter autour. L’avenir nous le dira.

Utiliser PHP en Bash

Pour revenir à nos moutons, nous souhaitions exploiter du JSON en Bash avec PHP. On va tenter d’y aller étape par étape. Il s’agit tout d’abord d’exécuter un script PHP depuis un script Bash ou directement depuis un shell.

Nous partirons sur 2 fichiers : un script Bash, l’autre un PHP, tous 2 dans le même dossier.

Voilà le contenu du fichier ‘disk.php’, qui ne fera que retourner une valeur au script Bash :

À présent, le fichier ‘test.sh’, le fichier Bash :

#!/bin/bash
echo "Nombre de disques : " $(php -f $(dirname $0)'/disks.php')

Si vous lancez à présent le script test.sh, que vous aurez rendu exécutable auparavant, vous aurez ceci :

Nombre de disques :  5

J’explique :

Pour lancer un script PHP depuis Bash, il suffit de faire

php -f chemin/du/script.php
  :
  • php
      est la commande permettant de lancer la fonction PHP, que vous aurez installé bien sûr…
  • L’option
    -f
      indique qu’on souhaite exécuter un fichier et non pas une commande
  • Le dernier argument est le chemin et le nom du script à traiter.

Au cas où :

dirname $0
  permet de récupérer le chemin absolu du script courant.

Enfin, il est bon de savoir que tout ce qui sortira du script PHP (les echo, print etc), ne seront pas affichés. Ils seront simplement retournés au script Bash.
On pourrait ainsi réécrire la partie Bash comme ceci, sans toucher au PHP :

#!/bin/bash
nbDisks=$(php -f $(dirname $0)'/disks.php')
echo "Nombre de disques : $nbDisks"

# Nombre de disques : 5

Ça ne changerait rien, PHP n’affiche rien. La valeur 5 serait simplement affectée à la variable

$nbDisks
 , qu’on afficherait ensuite.

Arguments

Tout ça c’est bien, mais c’est trop scolaire. À quoi sert d’appeler un script si on ne peut pas lui passer d’arguments ? Pas grand chose, en effet.
Il y a 2 méthodes pour passer des arguments à PHP depuis Bash, que nous allons voir.

Des arguments simples

Il s’agit de passer un seul argument, une seule valeur au script à exécuter.

Dans l’exemple qui va suivre, je souhaite récupérer en Bash le nombres d’élèves de certaines classes. Si le nom d’un professeur est renseigné, on va chercher le nombre d’élèves de sa classe (on peut imaginer une requête SQL depuis PHP par exemple). Si aucun professeur n’est trouvé, on indique une erreur.
Enfin, si aucun nom n’est indiqué, on retourne le nombre d’élèves de toutes les classes.

Script PHP :

2 points tout de même :

  • $argv
      est un tableau contenant les arguments passés au script lorsque PHP est utilisé en CLI. Quelque soit le nombre d’arguments,
    $argv[0]
      contient le chemin et le nom du script en cours.
  • $argc
      contient le nombre d’arguments passés au script. Lorsque aucun argument n’est donné, cette variable est égale à 1.

Passons au script Bash :

#!/bin/bash

echo "Nombre d'élèves dans la classe de Mme Michu : "$(php -f $(dirname $0)'/students.php' 'michu')
echo "Nombre d'élèves dans la classe de Foo : "$(php -f $(dirname $0)'/students.php' 'foo')
echo "Nombre d'élèves total : "$(php -f $(dirname $0)'/students.php')
echo "Nombre d'élèves chez Bar : "$(php -f $(dirname $0)'/students.php' 'bar')

Le résultat :

Nombre d'élèves dans la classe de Mme Michu : 28
Nombre d'élèves dans la classe de Foo : 34
Nombre d'élèves total : 62
Nombre d'élèves chez Bar : Pas de classe avec ce professeur

À noter qu’il est possible de passer plusieurs arguments avec cette méthode, simplement en les espaçant :

echo $(php -f $(dirname $0)'/students.php' 'michu' 'plop' 55 'baz')

Cette méthode permet de passer plusieurs valeurs simplement, mais elle ne couvre pas tous les besoins.

Bon à savoir : Chaque argument est envoyé comme une chaîne de caractères, qu’il soit entouré de guillemets ou pas.
Aussi, dans l’exemple précèdent, le ’55’ passé au script sera de type string lorsqu’il sera utilisé par PHP.

Arguments associatifs

Il existe une astuce que j’ai découvert il y a peu, c’est de pouvoir passer des paramètres avec un nom et une valeur à un tel script. Quelle utilité à vrai dire ?
Dans l’exemple précèdent, avec les classes et le nombre d’élèves, comment passer au script que la classe de Mme Michu possède maintenant 30 élèves ?

Et bien il suffit de passer les paramètres précédés d’un double tiret

--
  et de les assigner comme suit :
#!/bin/bash

echo "$(php -f $(dirname $0)'/disks.php' -- 'nom=Mme Michu' eleves=30)"

Coté PHP, nous allons toujours utiliser les variables $argc et $argv. Cependant, pour pouvoir les utiliser correctement, il va falloir faire une petite manipulation :

Une fois le script Bash lancé, le résultat sera celui-ci :

Array
(
    [0] => /home/maxk/bin/students.php
    [1] => nom=Mme Michu
    [2] => eleves=30
)
Mme Michu a dans sa classe 30 élèves

Je n’explique pas le print_r($argv), je pense que vous comprendrez. En revanche, on voit clairement que pour exploiter les arguments, il va falloir séparer le nom de l’argument (nom et eleves) de leurs valeurs (Mme Michu et 30).

C’est ce que fait le script ensuite : Il explose chaque argument s’il y en a avec le signe ‘=’, et on se retrouve avec un tableau ($args) qui contient les arguments exploitables. Pas beau ça ?

Variables globales

Avant d’attaquer les choses sérieuses, je voulais vous parler d’un petit truc qui m’est bien utile.
Dans mes scripts, j’ai régulièrement besoin de passer des variables de Bash à PHP. Je peux utiliser les arguments décrits ci-dessus bien sûr, mais il existe des cas où cela devient redondant.
C’est le cas par exemple lorsqu’il s’agit de passer encore et toujours la même valeur, la même variable.

En Bash

Il est possible de passer, en Bash, des variables en globales, c’est à dire que cette variable sera connue de tous les scripts qui seront exécutés.

Vous connaissiez cette façon pour assigner une valeur à une variable :

foo='je suis locale'

Et bien, il y a une autre façon de déclarer une variable pour qu’elle soit globale, qu’elle puisse être utilisée dans tous les scripts lancés depuis le processus :

export bar='je suis globale'

La variable

bar
  est ici accessible depuis n’importe quel script ! Essayons cela.
Créez un fichier qui va déclarer 2 variables, une locale et une globale, et qui lancera un autre script Bash :
#!/bin/bash

foo='je suis locale'
export bar='je suis globale'

$(dirname $0)'/export.sh'

Puis créez le second fichier, export.sh, qui sera appelé depuis le premier script, et qui aura pour simple fonction d’afficher le contenu de ces 2 variables :

#!/bin/bash

echo $foo
echo $bar

Lançons le premier script (test.sh) et observons le résultat :

je suis globale

Seul le résultat de $bar est affiché, car

$foo
  n’est pas connu du script export.sh. En revanche, Bash ne lève aucune erreur si une variable n’existe pas, elle sera simplement considérée comme une chaîne de caractères vide.

En PHP

À présent, voyons comment récupérer une variable globale déclarée en Bash depuis PHP.
Cela est possible grâce à la fonction getenv(), qui permet de récupérer une variable de l’environnement.

Comme tout à l’heure, nous allons déclarer une variable globale dans notre script, et appeler un script PHP, qui devra l’afficher :

#!/bin/bash

foo='je suis locale'
export bar='je suis globale'

echo $(php -f $(dirname $0)'/disks.php')

Et le script PHP :

Lançons le script Bash, et voyons le résultat :

Foo : 
Bar : je suis globale

Il est possible de récupérer les variables de Bash en PHP. Génial non ?
À savoir qu’une fois la variable déclarée avec

export
 , il est possible de la modifier à souhait en Bash, sans la précéder de
export
 , elle sera toujours globale.

Du JSON en Bash avec PHP

Maintenant que nous avons vu qu’utiliser PHP avec Bash n’était pas bien difficile, il est l’heure de nous intéresser au sujet important : Exploiter du JSON en Bash avec PHP.

Dans les exemples qui vont suivre, pour éviter les répétitions, nous partirons du principe que notre fichier JSON system.json contient ceci :

{
    "host": "Debian 8.9",
    "kernel": "3.16.0-4-586",
    "packages": {
        "yunohost": "2.6.4",
        "yunohost-admin": "2.6.1",
        "moulinette": "2.6.1",
        "ssowat": "2.6.8"
    },
    "system": {
        "disks": {
            "sda7": "Mounted on /tmp, 360.0MiB (358.0MiB free)",
            "sda5": "Mounted on /var, 2.7GiB (1.7GiB free)",
            "sda8": "Mounted on /home, 131.3GiB (130.8GiB free)",
            "sda1": "Mounted on /, 8.1GiB (6.7GiB free)"
        },
        "memory": {
            "ram": "2.0GiB (1.5GiB free)",
            "swap": "4.0GiB (4.0GiB free)"
        }
    },
    "apps": {
        "installed": "Firefox",
        "installed": "Netbeans",
        "installed": "VLC"
    }
}

Récupérer une valeur

Le plus simple pour démarrer, c’est de demander à PHP de nous retourner une simple valeur contenue dans ce fichier JSON.
Pour cela, il nous faudra en Bash fournir un argument : La clé que nous souhaitons récupérer. Le script PHP s’occupera de nous retourner le résultat.

Je vous donne le code complet du script PHP (je l’ai appelé system.php). Je me suis aidé des trucs que l’on a vu plus haut, et je vous explique le reste ensuite :

", $args['key']);
    foreach ($parts as $part) {
        if (isset($system->$part)) {
            $system = $system->$part;
        }
    }
}

// On retourne le résultat
echo $system;

Au début, on voit que je fais appel à la variable

ROOT_PATH
  qui sera définie dans le script Bash. Elle nous servira en PHP à aller récupérer le chemin du fichier JSON.
Puis on définit le chemin du fichier JSON à utiliser.

La partie suivante est expliquée en haut, jusqu’à la récupération du fichier JSON, que l’on décode en un objet JSON. Si vous n’êtes pas à l’aise avec l’utilisation de JSON en PHP, je ne peux que vous conseiller cet excellent article sur le sujet

Enfin, nous allons ‘découper’ chaque partie de la clé si elle est fournie, en cherchant les éventuels 

->
  présents, et tenter de récupérer la valeur correspondante dans le JSON. Par exemple en fournissant la clé ‘system->memory->ram’, le script va découper celle-ci en 3 parties et tenter d’accéder successivement à :
$system->system
 , puis
$system->system->memory
 , et enfin
$system->system->memory->ram
 .
Si celle-ci existe, sa valeur est retournée, sinon, on retourne la dernière valeur trouvée.

L’utilisation de ce script avec Bash est donc toute aisée, puisqu’il suffit de définir le dossier courant du script, la variable globale

ROOT_PATH
 , et la clé de la valeur à récupérer avec le nom ‘key’ :
#!/bin/bash

export ROOT_PATH=$(dirname $0)
echo "Version du kernel : " $(php -f $ROOT_PATH'/system.php' 'key=kernel')
echo "RAM : " $(php -f $ROOT_PATH'/system.php' 'key=system->memory->ram')

Résultat :

Version du kernel :  3.16.0-4-586
RAM :  2.0GiB (1.5GiB free)

Pas bien ça ? Si, c’est bien, mais pas tant que ça.
Imaginez que vous souhaitez récupérer tous les packages contenus dans le fichier JSON. Si vous ne les connaissez pas à l’avance, c’est impossible avec cette méthode.
C’est ce que nous allons voir tout de suite.

Récupérer un tableau

Si à première vue il est assez facile de passer un tableau de PHP à Bash, en réalité c’est tout autre. Comme vous le savez (ou le découvrez), PHP ne peut retourner que du texte à Bash. Il va donc falloir ruser pour récupérer un tel tableau.

Tableau indexé

Il s’agit simplement de récupérer une liste, sans notion d’association, de valeurs. On souhaite par exemple récupérer les applications installées dans notre fichier JSON, à savoir Firefox, Netbeans et VLC.

Comme dit juste au dessus, le problème est que le retour de PHP à Bash ne se fait que par une chaîne de caractères. Pour en extraire un tableau, il va donc falloir trouver un délimiteur, un truc qui va séparer chaque valeur.
Ce séparateur peut être plein de choses, comme un espace, un retour à la ligne, une lettre, …Dans tous les cas, il faut être certain de ne pas croiser ce caractère dans les données JSON à traiter.
Pour ma part, comme je sais que j’aurai éventuellement des espaces, des tabulations et des sauts de ligne, j’ai choisi d’utiliser un symbole que je ne croiserai certainement pas : ¶

Si l’on est sûr que les valeurs du tableau ne contiennent pas ce caractère spécial, on peut donc l’utiliser pour en séparer les valeurs.

On va modifier un peu notre script PHP pour que, si la clé demandée contient un tableau (objet StdClass de notre JSON), il nous retourne le tableau sous forme de chaîne de caractère, en séparant les valeurs par le caractère choisi plus haut :

", $args['key']);
    foreach ($parts as $part) {
        if (isset($system->$part)) {
            $system = $system->$part;
        }
    }
}

if (is_object($system)) {
    // La clé contient plusieurs valeurs
    $str = ""; // On initialise une chaîne vide
    foreach ($system as $key => $value) {
        $str .= $value . '¶';
        // On colle chaque valeur dans la chaîne et un séparateur
    }
    $system = $str;
    // On attribue cette chaîne à notre variable qui sera retournée au script Bash
}

// On retourne le résultat
echo $system;

J’ai mis en bleu les lignes que j’ai rajouté par rapport au script précédent. C’est ce bout de code qui va permettre de retourner toutes les valeurs si la clé passée ne contient pas qu’une seule valeur mais plusieurs.

Rien de compliqué là-dedans, vous devriez vous en sortir avec les commentaires. Passons au Bash :

#!/bin/bash

export ROOT_PATH=$(dirname $0)

declare -a apps

IFS='¶' read -a apps <<<$(php -f $ROOT_PATH'/system.php' 'key=apps')

for app in "${apps[@]}"
do
    echo $app
done

echo "Mon préféré est ${apps[1]}"

Plusieurs choses à noter ici :

  • declare -a apps
      : On déclare la variable apps comme un tableau indexé.
  • IFS
      : C’est une variable du Shell, qui définit le séparateur. Par défaut, elle contient un espace, une tabulation (\\t)et un retour à la ligne (\\n). Chaque caractère qu’elle contient est un séparateur à lui-seul, il n’est pas possible d’utiliser une suite de caractères.
    En le faisant suivre d’une autre instruction, le séparateur est modifié uniquement pour cette instruction.
  • read
      : Attend une réponse de l’utilisateur, comme un prompt
  • -a apps
      : Détermine le nom de la variable dans laquelle le résultat de read sera stockée.
  • <<<
      : Permet de ne pas attendre que l’utilisateur tape quelque chose, mais va envoyer la résultat du script PHP à l’instruction read, comme si l’utilisateur l’avait tapé lui-même dans le Shell.
  • On lance le script PHP system.php en donnant la clé ‘apps’, pour récupérer les applications de notre fichier JSON.

À l’issue de la commande

read
 …, la variable
$apps
  contient un tableau indexé avec les valeurs Firefox, Netbeans et VLC.

Puis on parcours simplement le tableau et on affiche chaque valeur.
Enfin, on affiche uniquement l’élément du tableau qui a pour index 1. Pour mémoire, les index commencent à 0.

Si on lance le script, voilà le résultat :

Firefox
Netbeans
VLC
Mon préféré est Netbeans

Tableaux associatifs

On touche au but, mais également la partie la plus chiante.
Toujours dans notre fichier JSON de départ, comment pourriez-vous associer les disques (sda7, sda5 etc) à leurs mémoires respectives ?
Depuis Bash 4, il est possible d’utiliser des tableaux associatifs. Et vous allez voir que ça vaut le coup de se faire chier un peu, car on va commencer à pouvoir profiter pleinement de notre fichier JSON.

Mais le problème rencontré à la création d’un simple tableau est double. Il va maintenant falloir séparer chaque entité du tableau, mais également séparer la clé de sa valeur. Pour cela j’ai utilisé une solution toute simple : J’ai pris un second caractère spécial : þ . Ainsi dans le script que PHP doit me retourner, un tableau va ressembler à ça :

clé1þvaleur1¶clé2þvaleur2¶...

Et Bash s’occupera de découper cela.
Mais il y a un autre soucis : Comment faire savoir à PHP que l’on souhaite récupérer un tableau associatif, et non pas un tableau indexé ?
Et bien nous allons encore une fois utiliser un argument, que l’on nommera ‘assoc’. Si celui-ci est passé à 1, alors PHP devra retourner un tableau associatif, sinon un tableau indexé.

Vous y êtes ? C’est parti !

", $args['key']);
    foreach ($parts as $part) {
        if (isset($system->$part)) {
            $system = $system->$part;
        }
    }
}

if (is_object($system)) {
    // La clé contient plusieurs valeurs
    $str = ""; // On initialise une chaîne vide
    foreach ($system as $key => $value) {
        if (isset($args['assoc']) && $args['assoc'] === '1') {
            // Tableau associatif
            // On colle chaque clé et valeur dans la chaîne
            // La clé est séparée de sa valeur
            $str .= $key . 'þ' . $value . '¶';
        } else {
            // Tableau indexé
            $str .= $value . '¶';
            // On colle chaque valeur dans la chaîne et un séparateur
        }
    }
    $system = $str;
    // On attribue cette chaîne à notre variable qui sera retournée au script Bash
}

// On retourne le résultat
echo $system;

Encore une fois j’ai mis les lignes ajoutées en évidence.
En gros si l’argument ‘assoc’ est passé à 1, on insère dans la chaîne de retour la clé et la valeur, avec les séparateurs choisis. Sinon, on n’insère que la valeur.

Passons au Bash à présent, ça risque d’être un peu long…

#!/bin/bash

export ROOT_PATH=$(dirname $0)

# On déclare le tableau indexé tmp
declare -a tmp

# On récupère les disques et on demande au script PHP un tableau associatif
IFS='¶' read -a tmp <<<$(php -f $ROOT_PATH'/system.php' 'key=system->disks' 'assoc=1')

# Déclaration du tableau associatif disks
declare -A disks

# On parcourt les disques stockés dans la variable $tmp
for disk in "${tmp[@]}"
do
    # On explose la clé de sa valeur à l'aide du second séparateur
    IFS='þ' read -a arr <<<$disk
    # On associe la clé et la valeur dans le tableau associatif
    # disks[cle]=valeur
    disks[${arr[0]}]=${arr[1]}
done

for K in "${!disks[@]}"
do
    echo $K --- ${disks[$K]}
done

# Déclaration d'un tableau pour les clés
declare -a keys
# On récupère toutes les clés des disques
keys=(${!disks[@]})

echo "Ma partition /var se nomme ${keys[2]} et est ${disks[${keys[2]}]}"

echo "Mais je peux utiliser ça aussi : ${disks['sda7']}"

Pratiquement tout a été modifié depuis l’étape plus haut.
J’ai modifié la variable

$apps
  en en
$tmp
 , car ce tableau n’est maintenant que temporaire : Une fois le script PHP exécuté, c’est un tableau contenant les clés et les valeurs sous cette forme :
clé1þvaleur1
clé2þvaleur2

Remarquez qu’on déclare ensuite le tableau

$disks
 . Ce n’est pas une faute de frappe, j’ai volontairement mis un A majuscule, à l’instar de
$tmp
 . Et oui, un tableau associatif sous Bash se déclare de telle façon :
declare -A montableau

Puis on parcourt les disques (la variable

$tmp
 ), dont on va extraire la clé et la valeur.
Pour cela, on utilise encore la méthode du
read <<<
 , avec un autre séparateur, le second (ici þ ). La clé et la valeur sont donc stockées dans un autre tableau temporaire,
$arr
 , puis on stocke ces 2 informations dans notre tableau associatif
$disks
 .
Vous suivez encore ?

Une fois la boucle

for disk in ...
  terminée, le tableau
$disks
  est rempli. Nous pouvons donc le parcourir afin d’y afficher son contenu. C’est ce que fait la boucle
for K ...
  qui suit.

Pour info, le ‘!’ dans l’instruction

${!disks[@]
  signifie que l’on souhaite regarder dans les clés du tableau associatif. Le « @ » est utilisé pour récupérer toutes les données.
On peut donc traduire vulgairement :

for K in "${!disks[@]}"

Par :

« Pour toutes les clés appelées K trouvées dans le tableau $disks »

Mais… À ce stade, il est impossible d’afficher un seul élément du tableau, ni la clé ni sa valeur (à moins de connaître la clé). Si vous pensiez pouvoir faire ceci :

echo "${!disks[1]}" # Incorrect

Et bien ça ne fonctionne pas. En fait, il n’y a pas moyen de récupérer la clé d’un tableau associatif en Bash.
C’est pour cela que le code suivant est fait :

# Déclaration d'un tableau pour les clés
declare -a keys
# On récupère toutes les clés des disques
keys=(${!disks[@]})

On va de nouveau créer un tableau indexé

$keys
 , et on va récupérer dans celui-ci toutes les clés de notre tableau
$disks
 .
À partir de ce moment là, on pourra récupérer la clé et la valeur de chaque élément indépendamment :
echo "Ma partition /var se nomme ${keys[2]} et est ${disks[${keys[2]}]}"

echo "Mais je peux utiliser ça aussi : ${disks['sda7']}"

Et le résultat de ce script :

sda1 --- Mounted on /, 8.1GiB (6.7GiB free)
sda7 --- Mounted on /tmp, 360.0MiB (358.0MiB free)
sda5 --- Mounted on /var, 2.7GiB (1.7GiB free)
sda8 --- Mounted on /home, 131.3GiB (130.8GiB free)
Ma partition /var se nomme sda5 et est Mounted on /var, 2.7GiB (1.7GiB free)
Mais je peux utiliser ça aussi : Mounted on /tmp, 360.0MiB (358.0MiB free)

On dit merci qui ?

En bonus

Comme je suis un mec bien, je vais vous donner une autre petite astuce sur les tableaux : Il est possible de connaître le nombre d’éléments que possède un tableau :

echo "Le tableau possède ${#disks[@]} éléments"
# Le tableau possède 4 éléments

Enjoy !

L’article Exploiter du JSON en Bash avec PHP est apparu en premier sur Max-Koder.

Gravatar de Max Koder
Original post of Max Koder.Votez pour ce billet sur Planet Libre.

Articles similaires

Journal du hacker : Liens intéressants Journal du hacker semaine #43

lundi 30 octobre 2017 à 00:01

Pour la 43ème semaine de 2017, voici 10 liens intéressants que vous avez peut-être ratés, relayés par le Journal du hacker, votre source d’informations pour le Logiciel Libre francophone !

Pour ne plus rater aucun article de la communauté francophone, voici :

De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !

Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. Rejoignez-nous pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !

Et vous ? Qu’avez-vous pensé de ces articles ? N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker ou bien dans les commentaires de ce billet :)

Gravatar de Journal du hacker
Original post of Journal du hacker.Votez pour ce billet sur Planet Libre.

Articles similaires

Marien Fressinaud : Lessy : versions et itérations

dimanche 29 octobre 2017 à 10:00

Je me suis intéressé ces derniers jours au système de sortie des nouvelles versions de Lessy. Cela peut paraître étonnant, mais décider d’un tel système est parfois compliqué et pose plusieurs problèmes.

Pour commencer, on peut se poser la question « pourquoi versionner ? ». J’y vois personnellement quatre intérets en particulier :

Lorsque je travaillais encore sur FreshRSS, nous nous étions souciés de la question de la visibilité. Nous avions alors trois versions distinctes : une stable, sortant à intervalles plutôt longs, la bêta qui sortait tous les… hum… deux mois (?) et la version de développement. Nous avions décidé de mettre en avant la version bêta qui était alors moins testé que la version stable mais qui avait l’avantage de garder les utilisateurs accrochés à « l’actualité » de FreshRSS. Ce système avait toutefois le désavantage d’être lourd à maintenir. Je souhaitais par conséquent un système plus simple pour Lessy tout en continuant de mettre en avant le travail quotidien effectué.

Concernant le deuxième point, à savoir que le versionnage donne une indication sur le niveau de modifications depuis la version précédente, je pense évidemment au système « semantic version ». Si ce système possède un intéret évident dans le cas de dépendances (ex. le logiciel A dépend du logiciel B dans sa version X), je ne le vois pas dans le cas d’un logiciel en « bout de chaine » tel que Lessy. C’est pourquoi je suis parti sur un système de nommage totalement différent.

La raison consistant à donner des numéros de version pour permettre de revenir en arrière en cas de soucis me paraît évidemment légitime bien que le cas se présente à mon avis de façon assez rare.

Enfin, sortir une nouvelle version est loin d’être uniquement une tâche technique. Il s’agit avant tout de fêter une nouvelle étape franchie dans le développement et de marquer d’une pierre blanche l’avancement pour pouvoir constater plus tard tout le chemin parcouru. Célébrer une nouvelle version, ça motive énormément !

Concrêtement, comment cela va-t-il se passer pour Lessy ?

L’ensemble des tâches à effectuer (fonctionnalités, tâches techniques, corrections de bugs, etc.) sont listées en vrac dans les tickets GitHub, ce qui me sert par conséquent de boite d’entrée. Ces tâches sont ensuite triées par petits groupes au sein d’itérations représentées par les projets GitHub. Les tâches d’une itération forment un ensemble de fonctionnalités ou tâches techniques similaires et leur temps de développement total effectif ne doit pas être excessif (je me fixe 2 ou 3 semaines comme maximum). Ces itérations permettent ainsi de dessiner une pseudo-roadmap du projet. Et comme chacune d’entre elles est nommée (d’après les constellations astronomiques), la fin d’une itération donne son nom à une nouvelle version de Lessy.

Ainsi, des quatre points que je listais plus haut, seul la problématique des dépendances n’est pas du tout adressé. Pour les trois autres :

Pour terminer, si j’ai choisi de nommer les versions de Lessy par les noms des constellations astronomiques, c’est avant tout parce que je cherchais un système de nommage original permettant de penser à autre chose qu’à seulement du code. Comme lever le nez du clavier ne suffit pas toujours à se changer les idées, je me disais que le lever vers le ciel serait une bonne idée.

Gravatar de Marien Fressinaud
Original post of Marien Fressinaud.Votez pour ce billet sur Planet Libre.

Pierre-Alain Bandinelli : Tomato by Shibby est mort ? Vive LEDE !

samedi 28 octobre 2017 à 21:35

Si j'en crois Wikipedia, l'histoire du micrologiciel Tomato remonte au vénérable Linksys WRT54G et au projet HyperWRT qui avait été développé pour ce routeur. HyperWRT a été supporté par les bénévoles de 2004 à 2008 et en 2008 un fork aura lieu et mènera à Tomato qui sera développé jusqu'en version 1.28. Et là, nouvel abandon, et nouveaux forks, celui de Shibby (un développeur polonais) acquiert une certaine renommée. En 2017, deux vulnérabilités majeures sont publiées :

Deux très bonnes raisons de mise à jour !

Tous les utilisateurs de firmware de routeurs & points d'accès se sont alors tournés vers les fournisseurs de ceux-ci, et les utilisateurs de Tomato by Shibby ont attendu avec impatience la sortie d'une nouvelle version. Malheureusement, deux semaines après ces annonces, aucun signe de vie et le site qui hébergeait les données de Tomato by Shibby n'est plus accessible au moment où j'écris ces lignes.

Il y a de nombreuses distributions basées sur Tomato by Shibby et d'autres forks de Tomato (cf. la page de Wikipedia sur Tomato, cependant si celle-ci est un jour, aucun des forks n'a été mis à jour post-annonce de KRACK ce qui n'augure rien de bon). Le code source étant disponible, de bonnes âmes expertes sauront peut-être faire renaître la tomate de ses cendres.

Pas de panique, il semble que LEDE soit une bonne alternative à Tomato dans la plupart des cas. Supporté par une communauté qui semble un peu plus large (Tomato by Shibby était, ne semble-t-il, soutenu que par un seul homme), LEDE est un fork d'OpenWRT. La dernière version 17.01.4 est très stable, très pratique et a été patchée pour KRACK !

Il est délicat de comparer LEDE et Tomato : là où Tomato se borne (bornait ?) à propulser routeurs et autres périphériques réseau, LEDE (Linux Embedded Development Environment) veut aller plus loin et propose une véritable micro-distribution avec gestion de paquets (avec l'utilitaire opkg). L'interface graphique LuCI de LEDE est très agréable, elle comporte moins de fonctionnalités que Tomato et il est probable qu'il faille recourir plus fréquemment à la ligne de commande de LEDE pour les paramétrages complexes possibles dans Tomato (par ex. la QoS, la gestion avancée des VLAN etc...). Mais dans les situations simples, LEDE peut-être un remplacement immédiat à Tomato. Pour les cas complexes, la migration est à évaluer, surtout si personne ne reprend le flambeau de Shibby !

Pour découvrir LEDE, c'est ici.

Gravatar de Pierre-Alain Bandinelli
Original post of Pierre-Alain Bandinelli.Votez pour ce billet sur Planet Libre.