jeudi 20 octobre 2011

rpmerizor

rpmerizor est un outil qui permet de générer très facilement un rpm lorsqu'on dispose des fichiers que le paquet est censé installer.
On le trouve ici.
Pour montrer comment cet outil peut être utilisé, nous allons revenir sur le cas traité dans le billet précédent.
Nous avons téléchargé le paquet libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb, puis nous en avons extrait le contenu...
[toto@rigel work]$ ar xv libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
[toto@rigel work]$ tar x --lzma -f data.tar.lzma
[toto@rigel work]$ tar xzf control.tar.gz
et effectué quelques petites manipulations:
[toto@rigel work]$ mv usr/lib usr/lib64
[toto@rigel work]$ mkdir work-b
[toto@rigel work]$ mv usr work-b
Et voilà, nous sommes prêts à utiliser rpmerizor. Après le lancement de la commande, il nous restera à fournir quelques informations (en bleu dans ce qui suit) dont certaines proviennent du fichier control du paquet debian (vive le copier-coller):
[toto@rigel work]$ rpmerizor -name libreoffice-sdbc-postgresql -version 0.8 --rootdir work-b
name: libreoffice-sdbc-postgresql
version: 0.8
A brief one line description.
SUMMARY> LibreOffice extension for PostgreSQL SDBC driver
The integer number of times you have built this rpm.
RELEASE> 0
toplevel_group/subclass (no biggie either way).
GROUP> Converted/misc
A sales pitch for the package.  A blank line means you are done.
DESCRIPTION> LibreOffice is a full-featured office productivity suite that provides
DESCRIPTION> a near drop-in replacement for Microsoft(R) Office.
DESCRIPTION> .
DESCRIPTION> The PostgreSQL SDBC Driver allows one to use the PostgreSQL database from
DESCRIPTION> LibreOffice without any wrapper layer such as ODBC or JDBC.
DESCRIPTION>
mkdir /home/toto/rpmbuild
mkdir /home/toto/rpmbuild/SPECS
write spec file on /home/toto/rpmbuild/SPECS/libreoffice-sdbc-postgresql-0.8.spec
Exécution_de(%prep): /bin/sh -e /var/tmp/rpm-tmp.spL2j6
+ umask 022
+ cd /home/toto/rpmbuild/BUILD
+ ln -s /home/toto/work/work-b /tmp/rpmerizor_buildroot
+ exit 0
Processing files: libreoffice-sdbc-postgresql-0.8-0.x86_64
Provides: config(libreoffice-sdbc-postgresql) = 0.8-0
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: /bin/sh
attention: Ne peut canoniser le nom d'hôte: rigel
Ecrit: /home/toto/rpmbuild/RPMS/x86_64/libreoffice-sdbc-postgresql-0.8-0.x86_64.rpm
Exécution_de(%clean): /bin/sh -e /var/tmp/rpm-tmp.tMJEcA
+ umask 022
+ cd /home/toto/rpmbuild/BUILD
+ rm /tmp/rpmerizor_buildroot
+ exit 0
package can be found on /home/toto/rpmbuild/RPMS
[toto@rigel work]$
Le produit a créé une arborescence rpmbuild standard:
Nous constatons qu'il a aussi créé un fichier spec que nous pouvons éditer pour y ajouter par exemple quelques dépendances requises:
Summary: LibreOffice extension for PostgreSQL SDBC driver
Name: %{name}
Version: %{version}
Release: 2
License: GPL
Group: Converted/misc

Requires: libreoffice-ure >= 3.3.3 libreoffice-core

%description
LibreOffice is a full-featured office productivity suite that provides
a near drop-in replacement for Microsoft(R) Office.
.
The PostgreSQL SDBC Driver allows one to use the PostgreSQL database from
LibreOffice without any wrapper layer such as ODBC or JDBC.
On peut alors construire un nouvel rpm tenant compte du spec modifié:
[toto@rigel ~]$ rpmbuild -bb --buildroot=/tmp/rpmerizor_buildroot ~/rpmbuild/SPECS/libreoffice-sdbc-postgresql-0.8.spec
Exécution_de(%prep): /bin/sh -e /var/tmp/rpm-tmp.NxDuhU
+ umask 022
+ cd /home/toto/rpmbuild/BUILD
+ ln -s /home/toto/work/work-b /tmp/rpmerizor_buildroot
+ exit 0
Processing files: libreoffice-sdbc-postgresql-0.8-0.x86_64
Provides: config(libreoffice-sdbc-postgresql) = 0.8-0
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: /bin/sh attention: Ne peut canoniser le nom d'hôte: rigel Ecrit: /home/toto/rpmbuild/RPMS/x86_64/libreoffice-sdbc-postgresql-0.8-0.x86_64.rpm Exécution_de(%clean): /bin/sh -e /var/tmp/rpm-tmp.4M2L2S + umask 022 + cd /home/toto/rpmbuild/BUILD + rm /tmp/rpmerizor_buildroot + exit 0
Cela n'apparait pas dans l'output, mais les dépendances requises ont bien été ajoutées au rpm
[toto@rigel ~]$ rpm -qp --requires ~/rpmbuild/RPMS/x86_64/libreoffice-sdbc-postgresql-0.8-0.x86_64.rpm
/bin/sh
config(libreoffice-sdbc-postgresql) = 0.8-0
libreoffice-core
libreoffice-ure >= 3.3.3
rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1

lundi 17 octobre 2011

Pilote postgresql sdbc: version 0.8

Ubuntu 11.10 est sorti et bonne nouvelle: il vient avec une toute nouvelle version, la version 0.8, du pilote libreoffice postgresql sdbc. Cette version remplace la version 0.7.6b qui avait un gros problème: elle permettait uniquement un accès en lecture seule. La nouvelle version est elle entièrement fonctionnelle. Il n'est donc plus nécessaire de retourner à OpenOffice 3.2 et à la version 0.7.6a du pilote (voir OOo base: retour vers le futur).
A nous les joies de LibreOffice 3.4. Pour y accéder à PostgreSQL via le pilote sdbc, il suffit d'installer le paquet libreoffice-sdbc-postgresql.
Il n'existe pas actuellement de paquet rpm pour la version 0.8 de ce pilote.
Pour une utilisation dans une distribution à base de rpm, on peut procéder comme ceci.
D'abord trouver et télécharger le fichier qui convient à son architecture, par exemple:
libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb.
Ensuite placer ce fichier dans un dossier work.
Puis:
[toto@rigel work]$ ar xv libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
[toto@rigel work]$ tar x --lzma -f data.tar.lzma
L'extraction du tar.lzma nous donne un répertoire usr:


Pour plus de facilités plaçons une copie du répertoire postgresql-sbbc-0.8.0 dans le répertoire work, copie que nous allons utiliser pour la constitution d'une archive zip.
[toto@rigel work]$ cp -r usr/lib/libreoffice/share/extensions/postgresql-sdbc-0.8.0/ .
[toto@rigel work]$ zip -r postgresql-sdbc-0.8.0.zip postgresql-sdbc-0.8.0/
  adding: postgresql-sdbc-0.8.0/ (stored 0%)
  adding: postgresql-sdbc-0.8.0/postgresql-sdbc.unorc (stored 0%)
  adding: postgresql-sdbc-0.8.0/description.xml (deflated 56%)
  adding: postgresql-sdbc-0.8.0/META-INF/ (stored 0%)
  adding: postgresql-sdbc-0.8.0/META-INF/manifest.xml (deflated 62%)
  adding: postgresql-sdbc-0.8.0/postgresql-sdbc-impl.uno.so (deflated 69%)
  adding: postgresql-sdbc-0.8.0/postgresql.xcu (deflated 64%)
  adding: postgresql-sdbc-0.8.0/postgresql-sdbc.uno.so (deflated 68%)
  adding: postgresql-sdbc-0.8.0/description/ (stored 0%)
  adding: postgresql-sdbc-0.8.0/description/description_en-US.txt (deflated 28%)
Nous disposons maintenant d'un fichier zip que nous pouvons ajouter en tant qu'extension à LibreOffice via le gestionnaire des extensions.
Avant de procéder, il convient toutefois d'effacer toute trace du pilote précédent.
[toto@rigel work]$ unopkg remove postgresql-sdbc-0.7.6b.zip
Si cette commande échoue:
[toto@rigel work]$ rm -rf ~/.libreoffice/3/user/uno_packages/
Dans le cas où l'installation du pilote précédent a été effectuée en root pour l'ensemble des utilisateurs:
[root@rigel work]# unopkg remove --shared postgresql-sdbc-0.7.6b
Il reste éventuellement à désinstaller le paquet qui a fournit l'extension.
Au lieu d'utiliser le gestionnaire des extensions, nous pouvons installer la nouvelle extension comme suit:
[root@rigel work]# cp -r postgresql-sdbc-0.8.0 /usr/lib64/libreoffice/share/extensions/
[root@rigel work]# unopkg add -v --shared /usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.8.0/
Évidemment dans ce cas, il n'était nul besoin du fichier zip.
Pour ceux que la copie dans /usr/lib64/libreoffice/share/extensions/ font hurler, il reste une alternative: construire un paquet rpm, ce qui peut être fait relativement aisément à l'aide de rpmerizor.
Une autre solution consiste à utiliser alien pour obtenir un rpm à partir du deb.
Cependant si à partir d'un paquet deb 64 bits par exemple, nous souhaitons une installation dans /usr/lib64 et non dans /usr/lib, il y a quelques manipulations à effectuer.
Procédons depuis Ubuntu.
toto@rigel:~work$ apt-get download libreoffice-sdbc-postgresql
Réception de : 1 Téléchargement de libreoffice-sdbc-postgresql 1:0.8.0+LibO3.4.3-3ubuntu2 [211 kB]
toto@rigel:~work$ ar xv libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
toto@rigel:~work$ tar xv --lzma -f data.tar.lzma
toto@rigel:~work$ tar xzvf control.tar.gz
./
./postinst
./preinst
./md5sums
./control
En plus du tar.lzma, nous avons cette fois extrait le tar.gz.
Remplaçons /usr/lib par /usr/lib64:
toto@rigel:~work$ mv usr/lib usr/lib64
toto@rigel:~work$ sed -i.old 's/lib/lib64/' md5sums
Reconstruisons le paquet deb:
toto@rigel:~/Téléchargements/work$ mkdir -p work-b/DEBIAN
toto@rigel:~/Téléchargements/work$ mv usr work-b
toto@rigel:~/Téléchargements/work$ mv control md5sums work-b/DEBIAN
toto@rigel:~/Téléchargements/work$ sudo dpkg -b work-b libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
[sudo] password for toto:
dpkg-deb : avertissement : « usr/DEBIAN/control » contient le champ « Original-Maintainer » défini par l'utilisateur
dpkg-deb : avertissement : 1 avertissement ignoré sur le(s) fichier(s) « control »
dpkg-deb : construction du paquet « libreoffice-sdbc-postgresql » dans « libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb ».
Le paquet deb ainsi obtenu n'est pas destiné à être utilisé dans Ubuntu, mais bien à être transformé en rpm avec alien:
toto@rigel:~work$ sudo alien --to-rpm libreoffice-sdbc-postgresql_0.8.0+LibO3.4.3-3ubuntu2_amd64.deb
[sudo] password for toto:
libreoffice-sdbc-postgresql-0.8.0+LibO3.4.3-4.x86_64.rpm generated
Ce paquet peut maintenant être installé dans une distribution à base de rpm.
Avec Fedora 15 en tout cas, tout se passe bien et le pilote fonctionne avec LibreOffice 3.3.3.

mardi 11 octobre 2011

Deuxième session

Utilisons le menu de notre distribution préférée pour changer d'utilisateur.
Ça fonctionne: c'est merveilleux! En fait nous avons ouvert une deuxième session graphique en parallèle avec la première qui est encore bien présente.
Comment faire pour y revenir?
Examinons la situation:


Nous constatons que la première session est associée au terminal virtuel tty7 et la deuxième à tty8.
Nous pouvons donc basculer entre les deux sessions  à l'aide de CTRL-ALT-F7 et CTRL-ALT-8.
Il arrive cependant que l'item du menu 'Changer d'utilisateur' soit inopérant et ceci principalement en cas d'utilisation d'un autre bureau que celui par défaut. Plutôt que de se casser la tête pour y remédier, il est préférable de procéder manuellement.
Basculons vers tty2 (CTRL-ALT-F2) pour nous y connecter en tant que l'utilisateur qui sera propriétaire de la future deuxième session graphique.
Ensuite nous lançons la commande startx et recevons en retour une flopée de message d'erreurs, parmi lesquels celui-ci (qui n'est pas dénué de sens):
Fatal server error:
Server is already active for display 0
If this server is no longer running, remove /tmp/.X0-lock
and start again.
Evidemment, le serveur X qui va gérer la nouvelle session doit être démarré pour l'affichage (display) 1 et non pas 0 (comme on peut le constater ci-dessus sur l'ouput de la commande ps).
Recommençons cette fois avec la commande:
startx -- :1
Bingo: ça fonctionne. Tout baigne, sauf que cette fois on ne passe pas par la case 'display manager' (normal: on est déjà connecté) qui permet de choisir le type de session. Donc on se retrouve avec le bureau par défaut, ce qui n'est pas nécessairement notre désir le plus profond.
Certaines distributions comme Fedora (mais pas Ubuntu)  regardent dans le dossier /etc/sysconfig pour voir si les utilisateurs ne préfèrent pas un autre bureau que celui par défaut. Dans ce cas /etc/sysconfig contient un fichier desktop avec une ligne du genre:
DESKTOP=Bureau préféré.
Et bien vérifions:
[root@rigel ~]# cd /etc/sysconfig
[root@rigel sysconfig]# grep '^DESKTOP' desktop
grep: desktop: Aucun fichier ou dossier de ce type
[root@rigel sysconfig]#
Le fichier n'existe pas.
On peut aussi avoir ceci:
[root@rigel sysconfig]# grep '^DESKTOP' desktop
[root@rigel sysconfig]#
Le fichier existe mais il ne contient pas la ligne qui convient.
[root@rigel sysconfig]# echo 'DESKTOP=KDE' >> desktop
crée le fichier ad hoc ou si desktop existe déjà, y ajoute la ligne qui convient (si le bureau préféré est KDE).
Une autre possibilité est:
[root@rigel sysconfig]# grep '^DESKTOP' desktop
DESKTOP=GNOME
[root@rigel sysconfig]#
La définition du bureau préféré est bien présente, mais elle ne correspond pas à ce que nous voulons (dans l'hypothèse où notre bureau préféré est KDE).
Correction:
[root@rigel sysconfig]# sed -r -i.old 's/^(DESKTOP).*/\1=KDE/' desktop
Nous disposons donc maintenant d'un fichier desktop par la grâce duquel le bureau lancé par startx sera le bureau préféré de l'ensemble des utilisateurs.
Cependant, il nous est encore loisible de définir le bureau préféré d'un utilisateur donné. Il existe différentes façons de procéder dépendant de la distribution. Dans le cas de Fedora (et d'autres distributions), il suffit de créer un fichier ~/.Xclients:
[toto@rigel ~]$ echo 'startkde' > ~/.Xclients
[toto@rigel ~]$ chmod +x ~/.Xclients
('startkde' c'est bien sûr si le bureau désiré est KDE. Pour gnome mettre 'gnome-session')
A l'exécution de startx par un utilisateur, le système démarre le client préféré de cet utilisateur, à défaut le client préféré de l'ensemble des utilisateurs et enfin en l’absence de client préféré, le client par défaut de la distribution, suivant ce schéma (Fedora), réalisé avec kivio:


Examinons la situation dans le cas où une deuxième session a été lancée avec startx:

Le pid a été ajouté à l'output, de manière à pouvoir entrer plus dans les détails:
[toto@rigel ~]$  pstree -a 5360
bash
  └─startx /usr/bin/startx -- :1
      └─xinit /etc/X11/xinit/xinitrc -- /usr/bin/X :1 -auth /home/toto/.serverauth.6327
          ├─X :1 -auth /home/toto/.serverauth.6327
          └─ck-xinit-sessio /usr/bin/ssh-agent /home/toto/.Xclients
              └─sh /home/toto/.Xclients
                  ├─ssh-agent /home/toto/.Xclients
                  └─startkde /usr/bin/startkde
                      └─kwrapper4 ksmserver

xinit est appelé par startx qui lui intime (en l'absence du fichier ~/.xinitrc) d'exécuter le script /etc/X11/xinit/xinitrc aux fins de démarrer le programme client.
Si aucun script ne lui est désigné (ce n'est pas le cas s'il est appelé par startx), xinit recherche l'existence du fichier ~/.xinitrc. En l'absence de ce dernier, le client par défaut sera un xterm. Le serveur par défaut est X.
Ainsi la commande
xinit -- :1
a un effet plutôt surprenant: on bascule vers un écran sans gestionnaire de fenêtres, sans bureau, mais contenant un xterm (avec un shell bash). Dans cet xterm, on peut taper la commande startkde (par exemple), et voilà notre deuxième session sur les rails.
Une variante de la commande précédente est:
xinit -e 'startkde' -- :1
avec laquelle la deuxième session se lance sans que l'on ait plus à taper quoi que ce soit.
Cette dernière commande peut avoir une application assez amusante. Considérons que nous sommes aux commandes d'un système dans lequel X n'est pas démarré (ce qui correspond au niveau d'exécution 3 pour un grand nombre de distributions). La commande:
xinit -e 'gnome-system-monitor'
nous conduira vers un écran affichant graphiquement les performances du système.
On peut même lancer un éditeur graphique:
xinit -e 'gedit'
Mais tout ceci nous éloigne du sujet.
Pour le fun, signalons qu'il est possible de lancer une session graphique sans utilisation de xinit. Voici comment.
Depuis tty2, éventuellement en root si problème de droit, lancer X:
X :1
Depuis tty3:
xterm -display :1
Il reste à basculer vers le terminal virtuel où se trouve le xterm et y taper la commande adéquate (par exemple startkde).

Avec Ubuntu 11.04, il semblerait qu'il soit impossible de démarrer une session Unity sans passer par le display manager gdm.
Pour démarrer une session avec startx il convient donc de définir un bureau préféré (différent du bureau par défaut, à savoir Unity) en créant un fichier ~/.xsession contenant
gnome-session --session=classic-gnome (pour une session gnome normale)
startkde (pour kde)
Avec Ubuntu 11.10, startx peut maintenant ouvrir une session Unity, c'est la session par défaut et il n'est nul besoin d'un fichier ~/.xsession. Indiquons quand même que la commande qui serait à utiliser est simplement
gnome-session.
Il est également possible d'installer gnome shell tout en conservant un Unity fonctionnel. Pour que startx ouvre une session gnome shell, la commande est cette fois
gnome-session --session=gnome

dimanche 4 septembre 2011

GRUB

Présentation.
GRUB (Grand Unified Bootloader) est un programme qui a pour vocation première d'amorcer un système linux. Pour ce faire, une toute petite partie de GRUB, installée dans un secteur d'amorçage, charge d'abord un mini-noyau qui va procéder à l'affichage d'un menu. Un appui sur "Enter" démarre alors le système d'exploitation sélectionné. Appuyer sur "c" au lieu de "Enter"nous conduit dans un shell où nous pouvons taper diverses commandes. Affichons par exemple le contenu du fichier "hello" situé dans le répertoire personnel de toto situé sur la partition /home séparée /dev/sda9:


En fait, nous sommes déjà dans un mini système d'exploitation.
"Esc" nous renvoie dans le menu. Appuyer sur "e" nous permet d'éditer les différentes commandes du menu, mais les changements ne seront pas sauvegardés.
Où installer GRUB?
Le problème auquel on est confronté lors de l'installation d'une distribution linux est le choix du secteur d'amorçage où installer GRUB. Le secteur d'amorçage principal (MBR = Master Boot Record) ou secteur 0 du disque /dev/sda est habituellement proposé par défaut. Mais si le disque contient windows, valider ce choix conduira à la destruction du MBR de windows. Aussi, dans le cas où un seul disque est disponible, il est conseillé d'installer GRUB sur le secteur d'amorçage (VBR = Volume Boot Record) de la partition racine du système installé où de la partition /boot si partition /boot séparée il y a.
Cas d'une installation sur un VBR.
L'adresse du mini-noyau à charger est inscrite dans le VBR sous forme d'une adresse en secteurs relative à l'origine du disque (et non de la partition). Voyons cela de plus près en examinant depuis notre OS linux les premiers octets du VBR dans lequel GRUB legacy (traditionnel) a été installé:
# od -Ax -v -tx1 -N 0x50 /dev/sda1
000000 eb 48 90 00 00 00 00 00 00 00 00 00 00 00 00 00
000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 02
000040 ff 00 00 80 9a 7f 00 00 00 08 fa 90 90 f6 c2 80
Le 'ff' à l'offset 0x40 indique que le  mini-noyau à charger se trouve sur le même disque. Dans le cas de GRUB legacy, il s'agit du fichier /boot/grub/stage2.
Les 4 octets à l'offset 0x44 contiennent l'adresse de ce fichier sous forme d'un nombre au format little-endian (octet de poids le plus faible à gauche). Dans le cas de notre exemple, cette adresse est 0x7f9a
Affichons le contenu du secteur situé à cette adresse:
# dd if=/dev/sda bs=512 count=1 skip=$((0x7f9a)) 2>/dev/null | od -Ax -tx1z
000000 52 56 5e bf f8 81 66 8b 2d 83 7d 04 00 0f 84 c4 >RV^...f.-.}.....<
000010 00 80 7c ff 00 74 3e 66 8b 1d 66 31 c0 b0 7f 39 >..|..t>f..f1...9<
000020 45 04 7f 03 8b 45 04 29 45 04 66 01 05 c7 04 10 >E....E.)E.f.....<
000030 00 89 44 02 66 89 5c 08 c7 44 06 00 70 50 66 31 >..D.f.\..D..pPf1<
000040 c0 89 44 04 66 89 44 0c b4 42 cd 13 0f 82 93 00 >..D.f.D..B......<
000050 bb 00 70 eb 56 66 8b 05 66 31 d2 66 f7 34 88 54 >..p.Vf..f1.f.4.T<
000060 0a 66 31 d2 66 f7 74 04 88 54 0b 89 44 0c 3b 44 >.f1.f.t..T..D.;D<
000070 08 7d 68 8b 04 2a 44 0a 39 45 04 7f 03 8b 45 04 >.}h..*D.9E....E.<
000080 29 45 04 66 01 05 8a 54 0d c0 e2 06 8a 4c 0a fe >)E.f...T.....L..<
000090 c1 08 d1 8a 6c 0c 5a 52 8a 74 0b 50 bb 00 70 8e >....l.ZR.t.P..p.<
0000a0 c3 31 db b4 02 cd 13 72 3a 8c c3 8e 45 06 58 c1 >.1.....r:...E.X.<
0000b0 e0 05 01 45 06 60 1e c1 e0 04 89 c1 31 ff 31 f6 >...E.`......1.1.<
0000c0 8e db fc f3 a4 1f 61 83 7d 04 00 0f 85 42 ff 83 >......a.}....B..<
0000d0 ef 08 e9 34 ff 5a ea 00 82 00 00 be 05 81 e8 3d >...4.Z.........=<
0000e0 00 eb 06 be 0a 81 e8 35 00 be 0f 81 e8 2f 00 eb >.......5...../..<
0000f0 fe 4c 6f 61 64 69 6e 67 20 73 74 61 67 65 32 00 >.Loading stage2.<
000100 2e 00 0d 0a 00 47 65 6f 6d 00 52 65 61 64 00 20 >.....Geom.Read. <
000110 45 72 72 6f 72 00 bb 01 00 b4 0e cd 10 46 8a 04 >Error........F..<
000120 3c 00 75 f2 c3 00 00 00 00 00 00 00 00 00 00 00 ><.u.............<
000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >................<
*
0001f0 00 00 00 00 00 00 00 00 9b 7f 00 00 f1 00 20 08 >.............. .<
Il s'agit bien du premier secteur du fichier /boot/grub/stage2, comme on peut facilement le vérifier avec la commande:
# od -Ax -tx1z -N 0x200 /boot/grub/stage2

Avec GRUB 2 (le nouveau GRUB), c'est un peu différent:
# od -Ax -v -tx1 -N 0x70 /dev/sda3
000000 eb 63 90 00 00 00 00 00 00 00 00 00 00 00 00 00
000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000050 00 00 00 00 00 00 00 00 00 00 00 80 40 f5 17 03
000060 00 00 00 00 ff fa 90 90 f6 c2 80 74 05 f6 c2 70
Le module à charger (mini-noyau) est cette fois /boot/grub/core.img dont le premier secteur est dans le cas de notre exemple situé à l'adresse 0x317f540:
# dd if=/dev/sda bs=512 count=1 skip=$((0x317f540)) 2>/dev/null | od -Ax -tx1z
000000 52 e8 28 01 74 08 56 be 33 81 e8 4c 01 5e bf f4 >R.(.t.V.3..L.^..<
000010 81 66 8b 2d 83 7d 08 00 0f 84 e9 00 80 7c ff 00 >.f.-.}.......|..<
000020 74 46 66 8b 1d 66 8b 4d 04 66 31 c0 b0 7f 39 45 >tFf..f.M.f1...9E<
000030 08 7f 03 8b 45 08 29 45 08 66 01 05 66 83 55 04 >....E.)E.f..f.U.<
000040 00 c7 04 10 00 89 44 02 66 89 5c 08 66 89 4c 0c >......D.f.\.f.L.<
000050 c7 44 06 00 70 50 c7 44 04 00 00 b4 42 cd 13 0f >.D..pP.D....B...<
000060 82 bb 00 bb 00 70 eb 68 66 8b 45 04 66 09 c0 0f >.....p.hf.E.f...<
000070 85 a3 00 66 8b 05 66 31 d2 66 f7 34 88 54 0a 66 >...f..f1.f.4.T.f<
000080 31 d2 66 f7 74 04 88 54 0b 89 44 0c 3b 44 08 0f >1.f.t..T..D.;D..<
000090 8d 83 00 8b 04 2a 44 0a 39 45 08 7f 03 8b 45 08 >.....*D.9E....E.<
0000a0 29 45 08 66 01 05 66 83 55 04 00 8a 54 0d c0 e2 >)E.f..f.U...T...<
0000b0 06 8a 4c 0a fe c1 08 d1 8a 6c 0c 5a 52 8a 74 0b >..L......l.ZR.t.<
0000c0 50 bb 00 70 8e c3 31 db b4 02 cd 13 72 50 8c c3 >P..p..1.....rP..<
0000d0 8e 45 0a 58 c1 e0 05 01 45 0a 60 1e c1 e0 03 89 >.E.X....E.`.....<
0000e0 c1 31 ff 31 f6 8e db fc f3 a5 1f e8 3e 00 74 06 >.1.1........>.t.<
0000f0 be 3b 81 e8 63 00 61 83 7d 08 00 0f 85 1d ff 83 >.;..c.a.}.......<
000100 ef 0c e9 0f ff e8 24 00 74 06 be 3d 81 e8 49 00 >......$.t..=..I.<
000110 5a ea 00 82 00 00 be 40 81 e8 3d 00 eb 06 be 45 >Z......@..=....E<
000120 81 e8 35 00 be 4a 81 e8 2f 00 eb fe bb 17 04 80 >..5..J../.......<
000130 27 03 c3 6c 6f 61 64 69 6e 67 00 2e 00 0d 0a 00 >'..loading......<
000140 47 65 6f 6d 00 52 65 61 64 00 20 45 72 72 6f 72 >Geom.Read. Error<
000150 00 bb 01 00 b4 0e cd 10 46 8a 04 3c 00 75 f2 c3 >........F..<.u..<
000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >................<
*
0001f0 00 00 00 00 41 f5 17 03 00 00 00 00 31 00 20 08 >....A.......1. .<
De nouveau, nous pouvons facilement vérifier que le secteur ainsi affiché est bien le premier secteur du fichier /boot/grub/core.img
GRUB installé sur un VBR ne fonctionnera plus en cas de remplacement du fichier /boot/grub/stage2 ou /boot/grub/core.img suivant le cas. En effet l'adresse (en secteurs) inscrite dans le VBR ne correspond plus à l'emplacement du fichier à charger.
Cas d'une installation sur le MBR.
Qu'en est-il si GRUB est installé sur le MBR?
# od -Ax -v -tx1 -N 0x50 /dev/sda
000000 eb 48 90 d0 bc 00 7c 8e c0 8e d8 bf 1d 06 be 1d
000010 7c 50 57 b9 e3 01 f3 a4 b5 03 f3 ab cb 80 fa 8f
000020 7e 02 b2 80 52 52 bb 94 07 8d af 2a 00 8a 46 04
000030 66 8b 7e 08 66 03 3e b2 06 84 c0 74 0b 80 03 02
000040 ff 00 00 20 01 00 00 00 00 02 fa 90 90 f6 c2 80
Nous voyons que le module qui sera chargé se trouve immédiatement après le MBR (il occupe le secteur 01).
Quel est ce module?
# od -Ax -tx1z -N 0x200 -j 0x200 /dev/sda
000200 52 56 5e bf f8 21 66 8b 2d 83 7d 04 00 0f 84 c4 >RV^..!f.-.}.....<
000210 00 80 7c ff 00 74 3e 66 8b 1d 66 31 c0 b0 7f 39 >..|..t>f..f1...9<
000220 45 04 7f 03 8b 45 04 29 45 04 66 01 05 c7 04 10 >E....E.)E.f.....<
000230 00 89 44 02 66 89 5c 08 c7 44 06 00 70 50 66 31 >..D.f.\..D..pPf1<
000240 c0 89 44 04 66 89 44 0c b4 42 cd 13 0f 82 93 00 >..D.f.D..B......<
000250 bb 00 70 eb 56 66 8b 05 66 31 d2 66 f7 34 88 54 >..p.Vf..f1.f.4.T<
000260 0a 66 31 d2 66 f7 74 04 88 54 0b 89 44 0c 3b 44 >.f1.f.t..T..D.;D<
000270 08 7d 68 8b 04 2a 44 0a 39 45 04 7f 03 8b 45 04 >.}h..*D.9E....E.<
000280 29 45 04 66 01 05 8a 54 0d c0 e2 06 8a 4c 0a fe >)E.f...T.....L..<
000290 c1 08 d1 8a 6c 0c 5a 52 8a 74 0b 50 bb 00 70 8e >....l.ZR.t.P..p.<
0002a0 c3 31 db b4 02 cd 13 72 3a 8c c3 8e 45 06 58 c1 >.1.....r:...E.X.<
0002b0 e0 05 01 45 06 60 1e c1 e0 04 89 c1 31 ff 31 f6 >...E.`......1.1.<
0002c0 8e db fc f3 a4 1f 61 83 7d 04 00 0f 85 42 ff 83 >......a.}....B..<
0002d0 ef 08 e9 34 ff 5a ea 00 22 00 00 be 07 21 e8 3f >...4.Z.."....!.?<
0002e0 00 eb 06 be 0c 21 e8 37 00 be 11 21 e8 31 00 eb >.....!.7...!.1..<
0002f0 fe 4c 6f 61 64 69 6e 67 20 73 74 61 67 65 31 2e >.Loading stage1.<
000300 35 00 2e 00 0d 0a 00 47 65 6f 6d 00 52 65 61 64 >5......Geom.Read<
000310 00 20 45 72 72 6f 72 00 bb 01 00 b4 0e cd 10 46 >. Error........F<
000320 8a 04 3c 00 75 f2 c3 00 00 00 00 00 00 00 00 00 >..<.u...........<
000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >................< *
0003f0 00 00 00 00 00 00 00 00 02 00 00 00 19 00 20 02 >.............. .<
Il s'agit du stage 1.5 qui contient tout ce qu'il faut pour charger ensuite le stage 2 via le système de fichiers. Le fichier stage 1.5 copié après le MBR lors de l’installation de GRUB, dépend du système de fichiers. Dans le cas d'un système de fichiers de la série ext2, il s'agit du fichier /boot/grub/e2fs_stage1_5. Ceci pour GRUB legacy.
Pour GRUB 2 les noms sont différents, mais le principe est le même.
La question qui vient à l'esprit est: pourquoi ne pas placer directement le stage 2 après le MBR?
Et bien par manque de place: seulement 62 secteurs sont disponibles entre le MBR et le début de la partition 1. Le stage 1.5 peut y prendre place.Dans le cas d'un système de fichier de la série ext2, il occupera 26 secteurs.
Toujours est-il qu'une installation de GRUB sur le MBR modifie non seulement le MBR, mais aussi d'autres secteurs. Avant de procéder à l'opération, il convient donc de sauvegarder, non seulement le MBR, mais aussi les 62 secteurs qui suivent.
Sauvegarde et restauration du MBR et des secteurs suivants.
Pour ce faire, insérons une clef usb qui se monte par exemple en /media/clef.
Puis:
# cd /media/clef
# dd if=/dev/sda of=mbr.img bs=512 count=1
# dd if=/dev/sda of=sda-1-62.img bs=512 skip=1 count=62
Pour restaurer:
# cd /media/clef
# dd if=mbr.img of=/dev/sda bs=446 count=1
# dd if=sda-1-62.img bs=512 count=62 seek=1 of=/dev/sda
On n’écrase pas la table des partitions (qui se trouve à l'offset 446) car celle-ci peut entre-temps avoir été modifiée.
Notons que même si l'intention est d'installer GRUB sur un  VBR, effectuer une copie de sauvegarde des 63 premiers secteurs du disque est quand même conseillé: il suffit de passer à côté de l'écran qui permet d'indiquer où installer GRUB et voilà le MBR et les secteurs qui suivent modifiés sans aucune possibilité de retour en arrière.
Booter sur une clef usb pour amorcer linux.
Comment amorcer notre OS si GRUB est installé sur le VBR?
Diverses possibilités s'offrent à nous. GRUB en tant que chargeur secondaire situé sur un VBR peut être appelé par le chargeur de windows (ou par tout autre chargeur situé sur le MBR).
Une autre solution est de booter sur une clef usb. Elle doit bien sûr avoir été préparée pour ce faire, mais ne doit pas être exclusivement réservée à cet effet. Cette clef (par exemple formatée en FAT32) peut contenir des données: celle-ci ne seront pas impactées.
Si la clef est montée en /media/clef et reconnue en tant que /dev/sdb (la partition montée étant /dev/sdb1), et à supposer que nous soyons dans un système linux utilisant GRUB 2, lançons la commande:
# grub-install --boot-directory=/media/clef /dev/sdb
ce qui aura pour effet d'installer GRUB dans le secteur d'amorce de /dev/sdb et de créer dans /media/clef un dossier grub avec tous les fichiers nécessaires sauf le fichier menu grub.cfg. Si nous voulons par exemple pouvoir appeler au choix un GRUB installé sur /dev/sda1 ou un autre installé sur /dev/sda3, il suffit de placer dans /media/clef/grub un fichier grub.cfg tel que:
# Fedora sur sda1
menuentry "Fedora " {
set root=(hd1,1)
chainloader +1
}
# Ubuntu sur sda3
menuentry "Ubuntu" {
set root=(hd1,3)
chainloader +1
}
GRUB 2 compte les disques à partir de 0 et les partitions à partir de 1. Mais comme nous bootons  sur la clef usb, /dev/sda devient pour GRUB le disque 2, c'est à dire hd1. Il sera peut-être nécessaire aussi de modifier le menu secondaire (celui vers lequel pointe le GRUB appelé) en y remplaçant hd0 par hd1. Rappelons que ceci peut s'effectuer en interactif par appui sur la touche "e", mais dans ce cas le changement n'est pas permanent.
Pour GRUB legacy, la commande à exécuter est quasiment la même:
# grub-install --root-directory=/media/clef/ /dev/sdb
Cette fois est créé le dossier /media/clef/boot/grub avec tout ce qui convient sauf le fichier menu grub.conf (ou menu.lst). Pour disposer des mêmes fonctionnalités que précédemment, il suffit de mettre dans /media/clef/boot/grub un grub.conf (ou menu.lst) contenant les lignes:
title Fedora
root (hd1,0)
chainloader +1
title Ubuntu
root (hd1,2)
chainloader +1
(GRUB legacy contrairement à GRUB 2 compte les partitions à partir de 0)
Le fichier menu se trouvant sur la clef est hors de portée des OS qu'il permet de lancer. En effet l'amorçage s'effectue par l'intermédiaire des menus secondaires (vers lesquels pointent les GRUB appelés) et ce sont ces menus qui sont mis à jour par l'OS.
Une réinstallation du ou des OS (par exemple pour un changement de version), ne nécessite pas que l'on change quoique que ce soit au niveau de la clef. Évidemment si on remplace Ubuntu par Linux Mint, il est peut être judicieux de mettre à jour le fichier menu de la clef (modifier un fichier texte n'est pas une tâche insurmontable), mais ce n'est pas absolument nécessaire dès l'instant où nous savons que le choix Ubuntu conduit en fait au lancement de Linux Mint.

samedi 30 juillet 2011

OOo base: retour vers le futur

La version de libreoffice-base actuellement livrée avec Ubuntu 11.04 est cassée en ce sens que les barres d'outils nécessaires pour modifier un formulaire ne s'affichent pas.
Alors, une solution consiste à installer openoffice.org à la place de libreoffice.
Mais tant qu'à faire, plutôt que d'installer la version actuelle (3.3), autant installer la version précédente (3.2.1). En effet, un autre problème se pose pour ceux qui désirent accéder à PostgreSQL via le pilote sdbc: l'accès aux données se fait en lecture seule avec les versions d'openoffice.org et de libreoffice >= 3.3.
Choisissons sur cette page le fichier qui convient à son architecture (OOo_3.2.1_Linux_x86-64_install-deb_fr.tar.gz, si on est en 64 bits).
Après avoir téléchargé le fichier, ouvrons un (émulateur de) terminal, et rendons-nous à l'endroit du téléchargement pour procéder à l'extraction du tar.gz:
toto@rigel: ~$ cd Téléchargements/
toto@rigel: Téléchargements$ tar xzvf OOo_3.2.1_Linux_x86-64_install-deb_fr.tar.gz
L'extraction a créé différents dossiers. Nous devons nous y rendre pour procédons à l'installation:
toto@rigel: Téléchargements$ cd OOO320_m18_native_packed-1_fr.9502/DEBS
toto@rigel: DEBS$ sudo dpkg -i *.deb
Et pour finaliser:
toto@rigel: DEBS$ cd desktop-integration/
toto@rigel: desktop-integration$ sudo dpkg -i *.deb
Reste à régler le problème du pilote sdbc. Recherchons et téléchargeons le paquet debian openoffice.org-sdbc-postgresql_0.7.6+OOo3.2.0-4ubuntu1_amd64.deb (qui convient pour du 64 bits). Essayant d'installer ce paquet, on se heurte à des problèmes de dépendances. Plutôt que de forcer l'installation, il est préférable de procéder en douceur. Créons un dossier de travail et mettons-y  le fichier téléchargé:
toto@rigel: Téléchargements$ mkdir work
toto@rigel: Téléchargements$ mv openoffice.org-sdbc-postgresql_0.7.6+OOo3.2.0-4ubuntu1_amd64.deb work
toto@rigel: Téléchargements$ cd work
toto@rigel: work$
Un paquet debian est une archive "ar" (et non pas "tar").
Procédons à l'extraction:
toto@rigel: work$ ar -xv openoffice.org-sdbc-postgresql_0.7.6+OOo3.2.0-4ubuntu1_amd64.deb
x - debian-binary
x - control.tar.gz
x - data.tar.lzma
toto@rigel: work$
Ce qui nous intéresse c'est le tar.lzma:
toto@rigel: work$ tar -xv --lzma -f data.tar.lzma
./
./usr/
./usr/lib/
./usr/lib/openoffice/
./usr/lib/openoffice/share/
./usr/lib/openoffice/share/extension/
./usr/lib/openoffice/share/extension/install/
./usr/lib/openoffice/share/extension/install/postgresql-sdbc-0.7.6a.zip
./usr/share/
./usr/share/doc/
./usr/share/lintian/
./usr/share/lintian/overrides/
./usr/share/lintian/overrides/openoffice.org-sdbc-postgresql
./usr/share/bug/
./usr/share/bug/openoffice.org-sdbc-postgresql/
./usr/share/bug/openoffice.org-sdbc-postgresql/script
./usr/share/bug/openoffice.org-sdbc-postgresql/presubj
./usr/share/doc/openoffice.org-sdbc-postgresql
toto@rigel: work$
Déplaçons le fichier zip dans le répertoire de téléchargement:
toto@rigel: work$
toto@rigel: work$ mv usr/lib/openoffice/share/extension/install/postgresql-sdbc-0.7.6a.zip ../
Nous aurons ainsi plus de facilité pour ajouter l'extension dans openoffice via "Outils-> Gestionnaire des extensions"
Nous pouvons maintenant détruire le répertoire de travail work.

mercredi 20 juillet 2011

Pilote postgresql sdbc 64 bits

Dans le billet Connecter openoffice à PostgreSQL, nous avons donné un lien permettant de télécharger le pilote sdbc.
Hélas, le pilote ainsi obtenu ne fonctionne pas si on est en 64 bits.
Certaines distributions fournissent un paquet 64 bits qui délivre le pilote en question. Par exemple chez Ubuntu, il s'agit du paquet libreoffice-sdbc-postgresql. Pour d'autres distributions ce paquet n'existe pas.
Voici comment contourner le problème. Ceci a été testé et fonctionne dans le cas de Fedora 15.
Tout d'abord, rechercher et télécharger, par exemple, le paquet libreoffice-base-drivers-postgresql-3.3.1.2-1.2.3.x86_64.rpm. Il s'agit d'un paquet openSuse.
Ensuite, dans un terminal, se rendre là où le paquet est téléchargé:
$ cd ~/Téléchargement 
$ rpm2cpio libreoffice-base-drivers-postgresql-3.3.1.2-1.2.3.x86_64.rpm | cpio -ivd
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/META-INF
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/META-INF/manifest.xml
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/description.xml
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/postgresql-sdbc-impl.uno.so
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/postgresql-sdbc.uno.so
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/postgresql-sdbc.unorc
./usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b/postgresql.xcu
1779 blocs
$

La commande rpm2cpio convertit le paquet RPM en archive cpio, archive qui est transmise à la commande cpio pour extraction. La commande cpio a créé dans "Téléchargement" toute une série de répertoires. Nous allons en premier ramener le répertoire "postgresql-sdbc-0.7.6b" dans "Téléchargement", puis créer le fichier zip adéquat:
$ mv usr/lib64/libreoffice/share/extensions/postgresql-sdbc-0.7.6b .
$ zip -r postgresql-sdbc-0.7.6b.zip postgresql-sdbc-0.7.6b
adding: postgresql-sdbc-0.7.6b/ (stored 0%)
adding: postgresql-sdbc-0.7.6b/postgresql-sdbc.unorc (stored 0%)
adding: postgresql-sdbc-0.7.6b/description.xml (deflated 52%)
adding: postgresql-sdbc-0.7.6b/META-INF/ (stored 0%)
adding: postgresql-sdbc-0.7.6b/META-INF/manifest.xml (deflated 62%)
adding: postgresql-sdbc-0.7.6b/postgresql-sdbc-impl.uno.so (deflated 68%)
adding: postgresql-sdbc-0.7.6b/postgresql.xcu (deflated 57%)
adding: postgresql-sdbc-0.7.6b/postgresql-sdbc.uno.so (deflated 71%)
$

Pour terminer, il suffit de procéder comme indiqué dans le billet Connecter openoffice à PostgreSQL:
$ cd $(dirname $(which soffice));cd $(ls -l soffice | sed -r 's/^.*>.(.*)soffice$/\1/')
$ unopkg add ~/Téléchargement/postgresql-sdbc-0.7.6b.zip
$
Il nous est bien sûr loisible de plutôt procéder à l'ajout l'extension via le Gestionnaire des extensions (menu Outils) de Libreoffice.

samedi 2 juillet 2011

Vous avez dit sourcer?

Pour mener à bien une compilation, nous avons besoin de définir toute une série de variables d'environnement. Les définitions de ces variables se trouvent par exemple dans un fichier nommé def-var:

export QTDIR=`kde4-config --qt-prefix`
export KDEDIR=`kde4-config --prefix`
export KDEDIRS=$KDEDIR
export KDE_BUILD=$KDEDIR
export DBUSDIR=$KDEDIR
export LD_LIBRARY_PATH=$QTDIR/lib:$KDEDIR/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=$DBUSDIR/lib/pkgconfig:/usr/lib/pkgconfig
export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH

Si nous exécutons def-var dans un terminal et que nous regardons ensuite ce qu'il en est au niveau des variables d'environnement existant dans le terminal, rien n'est changé.
Alors comment procéder? Taper toutes ces commandes?
Non, bien sûr: il existe une autre méthode.

Bon, reprenons en partant d'un fichier un peu plus ludique: le fichier bjr:

echo $PPID-$$
echo Saisis un nom $moi
read moi
cat << FIN
Toujours saluer le directeur:
Bonjour $moi
FIN

situé dans /home/toto/test.
Ce fichier contient toute une série de commandes.
Elles sont là, déjà écrites dans le fichier! Alors pourquoi les retaper?
Il suffit d'indiquer à bash que bjr constitue une source de commandes:


L'output de la commande echo est affiché en premier. Puis la commande "read moi" provoque l'affichage du curseur: le système est en attente de ce que nous allons taper au clavier afin de le mettre dans la variable moi:


Terminons la saisie par un appui sur ENTER:


Tapons effectivement à l'écran la première commande de bjr:


Le résultat est le même:  2849 est le pid du shell bash dans lequel nous sommes et 2838 celui de son processus parent (par exemple konsole ou gnome-terminal)
Lorsque bjr est sourcé, tout se passe comme si les commandes qu'il contient étaient tapées à l'écran. Ainsi la variable moi est maintenant définie dans le shell bash (pid 2849) avec la valeur "Ahuri".

Le mot "source" étant très long (et donc fatiguant à taper), il est le plus souvent remplacé par un point ("."):


Nous constatons que la variable moi est bel et bien définie (elle contient le mot "Ahuri") avant même l'exécution de la commande read

Et si nous exécutions bjr en tapant tous simplement son nom, comme pour n'importe quelle commande?
Problème:

C'est normal, bjr n'est pas trouvé car /home/toto/test ne figure dans la variable d'environnement PATH qui contient l'ensemble des répertoires où le système recherche les commandes.
Par curiosité, examinons le contenu de PATH:


/home/toto/test n'y figure évidemment pas, mais bien à toutes fins utiles /home/toto/bin.
Ainsi nous pourrions créer le lien symbolique qui convient.
ln -s ../test/bjr ../bin
Mais la réponse classique au problème consiste à indiquer au système où se trouve exactement la commande à exécuter en tapant:
/home/toto/test/bjr
ou plus court:
./bjr

En fait c'est la même chose:


Nous affichons d'abord les inodes des différents fichiers du dossier (y compris les fichiers cachés). En faisant une recherche sur l'inode 1717900 nous voyons que le fichier "." n'est autre que le dossier dans lequel on se trouve (/home/toto/test).
Ceci est bien connu et a déjà été expliqué dans un autre billet.

Le point (.) peut donc être mangé à plusieurs sauces.

Résumons:
. bjr : le point remplace la commande "source". bjr sera sourcé.
./bjr : le point remplace (ici) /home/toto/test. bjr sera exécuté.

Procédons à l'exécution (!):


Nouveau problème! Et oui: personne n'a le droit d'exécuter ce fichier, même pas le root.
Avant de procéder il faut d'abord donner le droit d'exécution sur bjr (avec la commande chmod +x bjr):


Intéressons nous à ce que vaut maintenant la variable moi dans le shell bash de base:


C'est encore la valeur résultant du "read" lorsque bjr a été sourcé pour la deuxième fois.

Constatations:
  • Les différentes commandes du script bjr, s'exécutent au sein d'un sous-shell (pid 2946) dérivé du shell bash principal (pid 2849).
  • Dans ce sous-shell, la variable moi n'est au départ pas définie (elle prend ensuite la valeur Jules).
  • L'exécution de bjr ne modifie pas la valeur de la variable moi dans le shell bash principal (contrairement à ce qui se passe lorsque bjr est sourcé).
    La variable moi n'est pas définie au départ dans le sous-shell où bjr tourne car ce n'est pas une variable d'environnement. Et quand bien même l'aurait-elle été (un petit export moi tapé à l'écran et hop!), cela aurait changé quoi ?
    • Elle aurait alors été définie d'emblée dans le sous-shell 2946 et la ligne 2 du résultat de l'exécution de bjr aurait été:  Saisis un nom Patate
    • Sa valeur serait comme avant restée inchangée au niveau shell maître
      Un changement de valeur dans un sous-shell ne se répercute pas dans le shell parent.

      Afin de consolider toutes ces notions, raisonnons maintenant sur un cas un peu plus compliqué, metttant en scène le fichier lbjr:

      echo $PPID-$$
      echo Bonjour $moi
      . defvar
      ./bjr
      echo Il répondra: appelez-moi $moi

      et le fichier defvar

      echo $PPID-$$
      moi=Big\ Boss

      (Remarquons le caractère d'échappement "\" qui enlève au blanc qui suit le mot "Big" son rôle de séparateur)

      Exécutons lbjr. Mais comme nous n'avons pas le courage de le rendre exécutable, procédons en utilisant la commande bash:


      Analysons le résultat:
      • ligne 1: lbjr s'exécute dans un sous-shell (pid 2949)
      • ligne 2: dans ce sous-shell la variable moi n'est pas définie
      • ligne 3: defvar est sourcé au niveau du sous-shell et la commande echo de defvar s'exécute bien dans ce sous-shell
      • ligne 4: bjr s'exécute dans un sous-sous-shell (pid 2950)
      • dernière ligne: bjr est terminé, on est retombé dans le sous-shell 2949 et la variable moi est est maintenant définie dans ce sous-shell car defvar y a été sourcé.
      Si defvar n'avait pas été sourcé, mais exécuté (commande ./defvar au lieu de . defvar), la variable moi serait restée non définie dans le shell pid 2949.

      Nous n'avons pas eu le courage de rendre lbjr exécutable, mais bash c'est quand même très long à écrire: pourquoi ne pas utiliser sh?
      Après tout sh est maintenant le plus souvent un simple lien vers bash:


      Et pourtant:


      Et oui : le comportement de bash change suivant la façon dont il est invoqué.
      Le mieux est d'indiquer précisément l'endroit où se trouve le fichier à sourcer, ce qui évite ce genre d'erreur.

      Pour en revenir avec le problème qui a motivé ce billet, la solution est bien évidemment de sourcer def-var dans le shell bash de travail. Les variables d'environnement, nouvelles où modifiées, seront ainsi présentes pour tous les processus fils