dimanche 26 avril 2015

Mise à jour table PostgreSQL

Sur une machine de bureau (appelée rigel), où est installé un serveur PostgreSQL, nous disposons d'une base de données bdtest.
La même base de données existe sur un ordinateur portable (aldebaran).
Au cours d'un voyage, des rangées ont été ajoutées à une table (nommée dépenses) sur l'ordinateur portable.
Il s'agit maintenant, travaillant depuis l'ordinateur portable, de mettre à jour la table dépenses sur l'ordinateur fixe.
Nous allons procéder simplement sans utilisation d'outils de synchronisation.
Evaluons tout d'abord la situation au niveau de l'ordinateur de bureau:

toto@aldebaran:~/SQL/bdtest$ psql bdtest -h rigel -t <<FIN
> SELECT max(référence)
> FROM dépenses
> FIN
Password: 
 2013-0023

2013-0023 n'est pas le mot de passe (celui-ci bien que tapé n’apparaît pas) mais bien le résultat du query.
Copions dans un fichier dépenses les rangées supplémentaires existant sur aldebaran:

toto@aldebaran:~/SQL/bdtest$ psql bdtest <<FIN
> \copy (SELECT * FROM dépenses \
> WHERE référence > '2013-0023') \
> TO dépenses
> FIN

Pour finir, connectons nous de nouveau à rigel pour copier les nouvelles rangées et vérifions ensuite que la mise à jour a bien été effectuée:

toto@aldebaran:~/SQL/bdtest$ psql bdtest -h rigel -t <<FIN
> \copy dépenses FROM dépenses
> SELECT max(référence)
> FROM dépenses
> FIN
Password: 
 2014-0019

En image:


jeudi 23 avril 2015

Meta-commande gset

Dans l'article Variables dans psql nous avons regretté le fait que l'instruction

SELECT ..
INTO ..

utilisée dans un terminal psql, serve à créer une nouvelle table et non à initialiser une variable.
En effet nous aurions aimé pouvoir exécuter quelque chose comme

SELECT code_u
INTO :code
FROM utilisations
WHERE signification = 'Santé';

et ensuite

SELECT *
FROM dépenses
WHERE code_u = :'code';

Mais cela ne fonctionne pas.

Une façon simple de contourner le problème consiste à envoyer l'instruction

SELECT code_u
FROM utilisations
WHERE signification = 'Santé'

vers le serveur avec la méta-commande gset et non avec un point-virgule.
La requête ne doit retourner qu'une rangée et chaque colonne de cette rangée sera stockée dans une variable portant le nom de la colonne.
Testons:



Il nous est loisible de donner à la variable un nom différent de celui prévu par défaut en modifiant l'instruction envoyée comme ceci:

SELECT code_u AS code
FROM utilisations
WHERE signification = 'Santé'

Testons:





Signalons que la deuxième instruction pourrait aussi s'écrire de la sorte:



Rappelons une autre solution présentée dans un billet précédent.
Il s'agit de créer une fonction avec

CREATE FUNCTION fdépenses(text)
RETURNS SETOF dépenses
AS $$
DECLARE
code dépenses.code_u%TYPE;
usage alias for $1;
BEGIN
SELECT code_u
INTO code
FROM utilisations
WHERE signification = usage;
RETURN QUERY SELECT *
FROM dépenses a WHERE code_u =  code  ORDER BY référence;        
END;
$$ LANGUAGE 'plpgsql';

dont l'utilisation conduit au même résultat:


dimanche 22 mars 2015

spin-orbite

Dans cet article nous allons donner des exemples d'utilisation de geogebra.
Geogebra est un outil qui permet des réalisations assez bluffantes : constructions géométriques, graphiques de fonctions, dérivées, intégrales, maxima etc.
Nous avons voulu  explorer un terrain, moins flamboyant, plus aride, à savoir celui du calcul matriciel.
Travaillant sous ubuntu 14.04 nous avons ajouté le dépôt geogebra aux sources de logiciel (voir ici) afin de pouvoir installer le paquet geogebra5 qui fournit une version de geogebra  avec la fenêtre de calcul formel.
Plutôt que de traiter d'un problème purement mathématique, nous avons préféré aborder un cas concret issu de la physique quantique. Il s'agit d'un cas relativement ardu que nous avons essayé de simplifier au maximum. Tout une série de développements théoriques seront passés sous silence. Cependant, bien que le but déclaré soit de montrer des exemples d'utilisation de geogebra, nous n'hésiterons pas à donner la signification physique des propriétés mathématiques rencontrées : de la sorte même le non initié pourra goûter à la beauté de cette théorie.

Considérons un électron (dans un atome) possédant un moment cinétique orbital l = 1.  Aie ! Tout de suite des mots qui fâchent : moment cinétique orbital. Mais il n'est pas nécessaire de comprendre ce qu'il en est exactement pour la suite du raisonnement. L'important est de savoir qu'une mesure de ce moment suivant un certain axe (z), une mesure d'une grandeur qui sera notée lz , ne peut donner que 3 résultats : +1, 0, -1 (dans un système d'unités adapté) . C'est extraordinaire puisqu'une grandeur physique varie normalement de manière continue. Mais il s'agit ici de physique quantique. A ces 3 valeurs correspondent 3 états notés |1>, |0>, |‑1>.  Ces 3 états sont des états particuliers de l'ensemble des états du moment cinétique, ensemble qui est appelé l'espace des états. Cet ensemble jouit de propriétés telles qu'il s'agit d'un espace vectoriel. Les éléments de cet espace, les états,  peuvent certes s'appeler vecteurs, mais ceux-ci n'ont rien à voir avec les vecteurs tels qu'on les conçoit communément (flèches). A la grandeur physique lz correspond un opérateur lz agissant dans cet espace. L'action de lz sur les états |1>, |0>, |‑1> est donnée par

lz |m> = m |m> (m = 1, 0, -1)

Le vecteur état est multiplié par la valeur de  lz  dans l'état.
On dit que les états |m> sont des états propres de lz avec la valeur propre m.
Toute combinaison linéaire a |1> + b |0> + c |‑1> défini un autre état. Les 3 états (normalisés)  |1>, |0>, |‑1> constitue une base de l'espace des états considéré qui est donc un espace à 3 dimensions.  Dans cette base un état quelconque est représenté par une matrice colonne :


Les opérateurs sont représentés par des matrices carrées 3X3. Faire agir un opérateur sur un état revient à multiplier la matrice colonne état par la matrice de l'opérateur, ce qui redonne une matrice colonne.
Dans une base constituée de vecteurs propres d'un opérateur, la matrice qui le représente est diagonale et les éléments diagonaux sont les valeurs propres.
Aux grandeurs physiques lx, ly , mesures du moment cinétique suivant les axes  x, y (qui constituent avec l'axe z le référentiel) correspondent, tout comme pour lz, des opérateurs lx, ly qui agissent dans l'espace des états. 
Les opérateurs lz, lx, ly sont représentés par les matrices:

Pour la matrice de lz le résultat est évident au vu de ce qui précède. Pour les 2 autres matrices, il faudra admettre le résultat vu que nous faisons l'impasse sur de nombreux développement théoriques. Pour ly précisons que i représente l'unité imaginaire qui s'obtient dans geogebra avec ALT +  i .

Les valeurs possibles pour lz sont les valeurs propres de la matrice correspondante. Il en est de même pour les autres grandeurs : les valeurs permises sont toujours les valeurs propres des matrices qui les décrivent.
Recherchons dans geogebra (fenêtre de calcul formel), les valeurs propres de l
Nous encodons 
l_x := 1/sqrt(2) {{0,1,0},{1,0,1},{0,1,0}}
pour la matrice de l
et 
Déterminant(l_x - λ Identité(3))

pour l''équation aux valeurs propres:


En ligne 2, geogebra a calculé le déterminant encodé et établi de manière formelle l'équation aux valeurs propres. Il nous reste à résoudre cette équation du second degré. Il suffit de sélectionner la ligne 2 et ensuite utiliser l'outil 'Résoudre' :


La ligne 2 est modifiée et y figurent maintenant les valeurs propres de lx qui sont identiques à celles de lz :


Rien que de plus normal : il n'y a aucune raison pour que les résultats d'une mesure suivant x soient différents des résultats d'une mesure suivant z. Les états (vecteurs) propres de lx sont des combinaisons linéaires particulières de |1>, |0>, |‑1>. Si lx est bien déterminé, lz ne l'est plus. Un état quelconque n'est sans doute état propre d'aucun des trois opérateurs lz, lx, ly . Il n'en est pas de même en ce qui concerne l'opérateur
l2 = lx2 + ly2 + ly2
En effet, on peut constater à l'aide de geogebra que l'espace des états tout entier est un espace propre de l'opérateur l2 avec la valeur propre l (l+1) = 2 :


Ce qui signifie que n'importe quel état a |1> + b |0> + c |‑1> (représenté par une matrice colonne) est état propre de l2 avec la valeur propre 2 :


Dans notre espace à 3 dimensions l² est donc parfaitement déterminé et vaut toujours l (l + 1) = 2.

Introduisons le spin de l'électron.  Il s'agit d'un autre moment cinétique qui (dans le modèle planétaire de l'atome) correspond à la rotation de l’électron sur lui-même. Celui-ci projeté sur un axe peut prendre les deux valeurs ±½ , ce qui multiplie par deux les possibilités. L'espace à 3 dimensions présenté plus haut devient un espace à 6 dimensions sous-tendu par les états (vecteurs) :
|1 +>, |1 ‑>, |0 +>, |0 ‑>, |‑1 +>, |-1 ‑> . 
états propres communs à lz et sz, opérateur lié à sz, mesure du spin suivant l'axe z:


lz |m±> = m |m±> (m = 1, 0, -1)
             sz |m±> = ±½ |m±>                           

Les matrices de  lz, lx, ly se transforment en matrices 6X6 par explosion de chacun de leurs éléments en 1 matrice 2X2 suivant le schéma :
Elles deviennent donc:

Les 3 opérateurs sz, sx, sy  correspondant aux composantes du spin sont dans notre espace à 6 dimensions (et avec la base choisie) représentés par les matrices :

Le long de la diagonale de ces matrices nous reconnaissons, reproduites chaque fois en 3 exemplaires les matrices 2x2 liées au spin telles qu'on les rencontre dans la littérature (scientifique).
Après avoir encodé toutes ces matrices 6x6 dans geogebra nous pouvons vérifier que notre espace des états à 6 dimensions reste espace propre de (avec la même valeur propre que précédemment)


et qu'il est espace propre de avec la valeur propre s (s+1) = 3/4 (s = 1/2) :


Maintenant nous allons passer à un niveau supérieur et aborder la composition du moment cinétique. Cependant nous allons nous efforcer de rendre la suite compréhensible même pour les non initiés.
Introduisons le moment cinétique total :

j = l + s

ce qui implique :
jz = lz + sz 

La matrice de jz s'obtient aisément à partir des matrices de lz et de sz:


La matrice est diagonale : tous les vecteurs base sont vecteurs propres de j.
De plus les sous-espaces ε1 (sous-tendu par |1 ‑> et |0 +>) et є2 (sous-tendu par  |0 ‑> et |‑1 +>) sont des espaces propres.
Les vecteurs de base sont-ils vecteurs propres de ?
Non, hélas !
Certes ils sont tous vecteurs propres de l² + s² avec la valeur propre 2 + 3/4 = 11/4 puisque comme nous venons de le voir l'espace des états est espace propre deet .
Malheureusement:
j² = l² + s² + 2 l.s

Construire la matrice de 2 l.s demande de fastidieux calculs. Avec geogebra, c'est plus simple: taper une seule ligne suffit :



La matrice n'est pas diagonale.
Cependant les vecteurs 1 et 6 de la base (|1 +> et |-1 ->) sont vecteurs propres de 2 l.s de valeur propre 1 et donc de avec la valeur propre j (j+1) = 11/4 + 1 = 15/4, soit j = 3/2 .
Comme ils sont aussi vecteurs propres de jz (valeur propre +3/2 et -3/2), nous les noterons |3/2 ±3/2> et pouvons écrire:


Pour le reste, les sous-espaces ε1 et ε2  sont globalement invariants (stables) sous l'action de l.s :
Le transformé par l.s d'un état de ε1 (ou ε2) est encore un état du même sous-espace.
De plus nous savons que ε1 et ε2 sont des espaces propres de jz. Donc les vecteurs propres de l.s (et donc de) présents dans ε1 et ε2 sont des vecteurs propres communs à et jz.
Procédons avec geogebra à la recherche des valeurs propres de 2 l.s dans ε1 :


Utilisons l'outil 'Résoudre'  après sélection de la ligne 2:
La ligne 2 est modifiée et y figurent maintenant les solutions de l'équation :


Nous retrouvons la valeur propre 1 déjà rencontrée.
Rappelons que si λ = 1 la valeur propre de est j (j + 1) = 2 + 3/4 + 1 = 15/4, soit j = l + 1/2 = 3/2.
Si λ = -2 la valeur propre de est j (j + 1) = 2 +3/4 -2 = 3/4, soit j = l – 1/2 = 1/2.

Recherchons le vecteur propre de valeur propre 1. Soient a et b les composantes de ce vecteur. En image les différentes étapes du calcul :


En ligne 3 nous écrivons que l'action de A sur le vecteur le laisse inchangé.
En ligne 4 nous indiquons la condition pour que cela se réalise.
En ligne 5 se trouve la condition de normalisation (nous supposons a et b réels)
Après avoir sélectionné les lignes 4 et 5, nous appliquons l'outil 'Résoudre', ce qui engendre la ligne 6 où figurent 2 solutions. Nous retenons la solution avec a positif. Notons ce vecteur |3/2 3/2> car j = 3/2 et ce vecteur appartient à ε1 qui est espace propre de jz avec la valeur propre 1/2.
Intéressons-nous maintenant au vecteur propre de valeur propre -2. Les étapes sont les mêmes que précédemment :


Cette fois j =1/2 comme expliqué précédemment et donc notre vecteur sera noté  |1/2 1/2>.
Suite aux résultats obtenus avec geogebra nous pouvons donc écrire:

Procédant de même dans ε2  nous obtenons cette fois :

Les coefficients qui apparaissent dans les relations ci-dessus ne sont rien d'autres que des coefficients de Clebsch-Gordan.

mardi 27 janvier 2015

Fonction bilan

A la fin du billet Variables dans psql, nous avions montré comment impacter le résultat d'instructions SQL (contenues dans un fichier) par initialisation d'une variable.
Ainsi

bdtest=> \set an 2013 
bdtest=> \i bilan.sql

donnera en ouput le bilan de 2013 pour autant que les instructions SQL de bilan.sql contiennent des clauses WHERE du genre:

WHERE an = :'an'

Nous pouvons aussi créer un fichier bilanx contenant la commande

psql bdtest -v an=$1 -f bilan.sql

L'année du bilan sera de la sorte transmise en paramètre au programme.
Il faut rendre bilanx exécutable:

toto@aldebaran:~/SQL/bdtest$ chmod +x bilanx

avant de pouvoir l'utiliser:



bilan.sql qui contient l'ensemble des instructions SQL se trouve sur le poste client (où est exécuté bilanx).
Nous voudrions ne pas avoir besoin de fichier contenant les instructions SQL et que celles-ci se trouvent sur le serveur.
Pour ce faire il nous faut créer une fonction (PL/pgsql). Si nous voulons retourner le même genre de bilan que dans le billet Sous-totaux dans terminal psql, cette fonction sera par exemple créée par:

DROP function fbilan (integer);
CREATE FUNCTION fbilan (integer)
RETURNS TABLE (mois text, "sous-total" text, ref char(9), datexec text, cred numeric(13, 2), deb numeric(13, 2), solde numeric(13,2), usage char(5))
AS $$
DECLARE
année alias for $1;
BEGIN
RETURN QUERY  
SELECT (A.mois_n ||' ' || A.mois), ' ', reference,
date_exec::text, crédit, débit,
  (SELECT SUM(B.solde)
  FROM opérationsv B
  WHERE B.reference <= A.reference
  AND B.an = A.an
  AND B.mois_n = A.mois_n),
  contrepartie
FROM opérationsv A
WHERE an::numeric = année
UNION
SELECT (C.mois_n ||' ' || C.mois), 'SOUS-TOTAL', '', '',
SUM(crédit), SUM(débit), SUM(C.solde),
'' 
FROM opérationsv C
WHERE an::numeric = année
GROUP BY C.mois_n, C.mois
UNION
SELECT 'TOTAL', '', '', '',
SUM(crédit), SUM(débit), SUM(D.solde),
''
FROM opérationsv D
WHERE an::numeric = année
ORDER by 1, 2 , 3;
END;
$$ LANGUAGE 'plpgsql';

Un problème se pose: la commande

psql bdtest -v an=$1 -c 'select * from fbilan(:an)'

conduit à une erreur:


alors que ceci:



fonctionne et donne le résultat escompté après un appui sur ENTER.

L'instruction  SQL constitue ce qui est appelé un here-document. Quelques éléments concernant cette notion se trouve dans le billet Les secrets de cat.

En conséquence, créons le fichier fbilax:

psql bdtest -v an=$1 -P numericlocale -P footer \
-P border=2 -P linestyle=u \
-P title='Bilan '$1 <<FIN
SELECT * 
FROM fbilan(:an)

FIN

Nous le rendons exécutable, puis nous le testons:


Ça fonctionne, mais si nous voulons améliorer l'output nous avons intérêt à utiliser awk.
Pour ce faire, créons le fichier fbilanx:

fichier=$(mktemp)
psql bdtest -v an=$1 -P numericlocale -P footer \
-P border=2 -P linestyle=u \
-P title='Bilan '$1 -o $fichier <<FIN
SELECT * FROM fbilan(:an); 
FIN
echo
awk 'NR==4 {y=$0};/SOUS-TOTAL/ {print y;print;print y};!/SOUS-TOTAL/' $fichier

dont l'utilisation après qu'il ait été rendu exécutable, nous fournit le résultat souhaité:


Grâce à l'option -o nous écrivons l'output de psql dans un fichier temporaire (créé par mktemp). Ce fichier temporaire sert d'input à awk. La ligne 4 (qui vient après le nom des colonnes) est alors mise en mémoire (première instruction awk) en vue d'une impression avant et après les lignes contenant le mot 'SOUS-TOTAL'. Pour les autres lignes, l'action par défaut (print) est exécutée. Le billet awk (introduction) contient tout ce qui est nécessaire pour la compréhension de ce qui précède.

Notons que si on est déjà dans un terminal psql, il n'est nul besoin de sortir pour procéder:



dimanche 14 décembre 2014

Session graphique inaccessible

Suite une réinstallation de Ubuntu (en vue de changer proprement de version), nous constatons que toute tentative de connexion via une session graphique est vouée à l'échec: après saisie du mot de passe, retour immédiat à l'écran d'accueil du display manager et ce sans aucun message d'erreur.
Dans notre cas, il s'agit de lightdm. Mais un autre display manager peut éventuellement afficher un message d'erreur.
Pour comprendre ce qu'il en est, nous basculons vers le terminal virtuel tty2: CTRL-ALT-F2.
Cette fois nous pouvons nous connecter.
Utilisons les commandes ls et id:

toto@aldebaran:~$ ls -ld ../toto
drwxr-xr-x 26 1001 1001 4096 déc  5 09:53 ../toto
toto@aldebaran:~$ id
uid=1000(toto) gid=1000(toto) groupes=1000(toto)
toto@aldebaran:~$ 

Dans l'ouput de la commande ls, le nom de l'utilisateur et de son groupe principal qui figurent habituellement en colonnes 3 et 4 sont remplacés par 1001. Donc il n'y a aucun utilisateur (et aucun groupe) dont l'id est 1001.
La commande id nous indique que l'utilisateur courant (toto) possède en fait l'uid et le gid 1000.
Explication: dans l'installation précédente toto n'était pas le premier utilisateur et il était effectivement caractérisé par un uid et un gid valant 1001. La réinstallation a été effectuée avec une partition /home séparée sans qu'elle soit formatée. Lors de la création de l'utilisateur toto, l'installateur a constaté que /home/toto existait déjà mais il n'a pas modifié les droits y afférents.
Solution du problème: réattribuer /home/toto à toto:

toto@aldebaran:~$ sudo -s
[sudo] password for toto: 
root@aldebaran:~# chown -R toto.toto ../toto
root@aldebaran:~# 

dimanche 31 août 2014

Pepper flash (suite)

Dans l'article précédent, dont celui-ci constitue la suite, après quelques généralités sur le plugin 'pepper flash' et son emploi avec chromium, nous avons traité uniquement du cas de ubuntu 14.04. Nous allons cette fois nous intéresser à d'autres distributions à commencer par Fedora (20).
Déjà l'installation de chromium n’est pas évidente car celui-ci ne fait pas partie de l'offre logicielle par défaut.
Pour en disposer, il faut avant de procéder à cette installation, configurer le dépôt churchyard-chromium-russianfedora:
 
[root@rigel ~]# cd /etc/yum.repos.d && wget -O churchyard-chromium-russianfedora.repo http://copr.fedoraproject.org/coprs/churchyard/chromium-russianfedora/repo/fedora-20-x86_64/
[root@rigel yum.repos.d]# yum install chromium

Cependant ce dépôt fournit très peu de paquets et aucun qui ait un lien avec le plugin pepper flash:


Pour pouvoir disposer du paquet qui installe le plugin, à savoir chromium-pepper-flash, il faut en plus configurer le dépôt russianfedora-nonfree. Cependant l’ajout de ce dépôt nécessite le dépôt russianfedora-free que nous pouvons cependant désactiver par la suite (par exemple avec la commande sed):

[root@rigel ~]# yum install http://mirror.yandex.ru/fedora/russianfedora/russianfedora/free/fedora/releases/20/Everything/x86_64/os/russianfedora-free-release-20-1.R.noarch.rpm
[root@rigel ~]# yum install http://mirror.yandex.ru/fedora/russianfedora/russianfedora/nonfree/fedora/releases/20/Everything/x86_64/os/russianfedora-nonfree-release-20-1.R.noarch.rpm
[root@rigel ~]# sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/russianfedora-free.repo
[root@rigel ~]# sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/russianfedora-free-updates.repo
[root@rigel ~]# yum install chromium-pepper-flash

Dans chromium, au niveau de l'URL chrome://plugins, en affichant + de détails, il est possible de désactiver l'ancien plugin, si celui-ci a été installé:

Dans le cas de la distribution Manjaro (ou Archlinux), pour disposer du plugin, il suffit d'installer le paquet chromium-pepper-flash à partir du dépôt AUR:

[toto@rigel ~]$ yaourt -S chromium-pepper-flash 

Le paquet est construit sur place après téléchargement du rpm google-chrome et extraction du plugin:



Dans d'autres distributions comme par exemple Chakra, le plugin est fourni avec le paquet qui contient le navigateur (chromium):


C'est la solution la plus simple mais qui ne convient pas à tout le monde.
Dans tous les cas évoqués ci-dessous, la mise à jour du plugin, une fois celui-ci installé, s'effectue automatiquement avec les autres mise à jour (contrairement à ce qui se passe pour Ubuntu 14.04)

dimanche 24 août 2014

Pepper flash

Le plugin flash livré par adobe pour certains navigateurs (dont firefox) est resté bloqué sur la version 11. Certes des mises à jour de sécurité sont encore fournies mais sans plus. De ce fait certaines animations ne fonctionnent plus correctement.
Cependant une version plus récente de ce plugin est intégrée dans google chrome. Cette version utilise l'API pepper (PPAPI) également disponible dans le navigateur chromium (mais pas dans firefox).
Il doit donc être possible d'utiliser cette version du plugin avec chromium.
Sous ubuntu 14.04 il suffit d'installer le paquet  pepperflashplugin-nonfree.
Mais attention: la version du plugin qui a été installée est figée: il n'y a pas de mise à jour, même si le système a lui été mis à jour et même si une nouvelle version du plugin existe.
Nous verrons en fin de billet comment procéder pour mettre à jour le plugin.
Essayons tout d'abord de comprendre pourquoi il faut procéder de la façon qui sera indiquée.
Téléchargeons le paquet afin de pouvoir l'analyser.

toto@rigel:~$ mkdir -p linux/pepper
toto@rigel:~$ cd linux/pepper
toto@:~/linux/pepper$ apt-get download pepperflashplugin-nonfree

Le fichier téléchargé est (dans notre cas) le paquet  pepperflashplugin-nonfree_1.3ubuntu1_amd64.deb
Il s'agit d'une archive 'ar' que nous allons décompresser:

toto@rigel:~/linux/pepper$ ar -xv pepperflashplugin-nonfree_1.3ubuntu1_amd64.deb 
x - debian-binary
x - control.tar.gz
x - data.tar.xz

Ce qui nous intéresse est le fichier control.tar.gz et plus précisément le script de post-installation (postinst) qu'il contient.
Afin de travailler proprement créons le dossier work/DEBIAN dans lequel nous allons décompresser control.tar.gz. On peut aussi décompresser data.tar.xz dans (dans work):

toto@rigel:~/linux/pepper$ mkdir -p work/DEBIAN
toto@rigel:~/linux/pepper$ tar -C work/DEBIAN -xzvf control.tar.gz 
./
./control
./prerm
./postrm
./postinst
./md5sums
toto@rigel:~/linux/pepper$ tar -C work -x --lzma -f data.tar.xz 

Il est possible d'arriver plus facilement au même résultat en utilisant l'outil dpkg-deb.
Une seule commande suffit après le téléchargement du fichier:

toto@rigel:~/linux/pepper$ dpkg-deb -R pepperflashplugin-nonfree_1.3ubuntu1_amd64.deb work

Le répertoire work est créé automatiquement.
Nous pouvons aussi, avec le même outil, extraire uniquement le contenu de control.tar.gz, mais alors nous devrons créer explicitement le fichier work (pour travailler dans la même arborescence):

toto@rigel:~/linux/pepper$ dpkg -e pepperflashplugin-nonfree_1.3ubuntu1_amd64.deb work/DEBIAN
dpkg-deb (sous-processus) : impossible de créer le répertoire: Aucun fichier ou dossier de ce type
dpkg-deb : erreur : le sous-processus tar a retourné une erreur de sortie d'état 2
toto@rigel:~/linux/pepper$ mkdir work
toto@rigel:~/linux/pepper$ dpkg -e pepperflashplugin-nonfree_1.3ubuntu1_amd64.deb work/DEBIAN

La commande suivante:

toto@rigel:~/linux/pepper$ head -7 work/DEBIAN/postinst 
#!/bin/sh

set -e

case "$1" in
    configure)
update-pepperflashplugin-nonfree --install --fast || true

montre que l'installation du plugin s'effectue au niveau du script de post-installation du paquet (qui s'exécute lors de l'installation du paquet).

L'installation du plugin consiste en fait à télécharger le paquet contenant google-chrome, à ne pas installer ce paquet mais à le décompresser et à mettre le plugin à disposition pour chromium.
Voici l'extrait du script qui correspond à ces deux dernières actions:

toto@rigel:~/linux/pepper$ awk '/dpkg-deb/,/mv/' work/usr/sbin/update-pepperflashplugin-nonfree 
dpkg-deb -x $debfile unpackchrome

sofile=unpackchrome/opt/google/chrome/PepperFlash/libpepflashplayer.so
[ -e $sofile ] || sofile=unpackchrome/opt/google/chrome-unstable/PepperFlash/libpepflashplayer.so
[ -e $sofile ] || sofile=unpackchrome/opt/google/chrome/PepperFlash/libpepflashplayer.so

mv -f $sofile /usr/lib/pepperflashplugin-nonfree

(Quelques explications sur le fonctionnement de awk se trouvent ici.)

L'utilisation du script update-pepperflashplugin-nonfree avec l'option status nous permet de vérifier si une nouvelle version du plugin est disponible, comme le montre cette copie d'écran effectuée juste après une mise à jour du système.


Pour installer la nouvelle version, il reste à exécuter la commande:

root@rigel:~# /update-pepperflashplugin-nonfree --install

En guise de vérification des assertions précédentes (la mise à jour s'effectue lors de l'exécution du script postinst), on peut aussi procéder comme suit:

root@rigel:~# dpkg-reconfigure pepperflashplugin-nonfree