Linux / Unix

Lister les répertoires présents dans le path

J’étais (malheureusement) déjà grand quand j’ai découvert awk :

Bien qu’il soit rebutant aux premiers abords, on arrive assez rapidement à faire des choses sympathiques !

Cet article vous montre une ligne simple pour lister les répertoires présents dans le path grâce à awk. La première chose à faire est d’envoyer le contenu de la variable d’environnement PATH à awk grâce à un pipe. Le programme awk commence  par changer le séparateur de champ (FS pour Field Separator) dans BEGIN puis boucle pour afficher les champs.

Voici la commande complète pour Unix :

echo $PATH | awk 'BEGIN {FS=":"} { for(i = 1; i <= NF; i++) print $i}'

Sous Windows, le séparateur est différent et la récupération de la valeur de la variable d’environnement est différente. De plus, Cmder (la ligne de commande que j’utilise depuis près d’un an et demi sous Windows) n’aime pas les chevrons donc j’utilise une boucle while à la place de la boucle for :

echo %PATH% | awk 'BEGIN {FS=";"} { i = 0; while(i++ != NF) print $i}'

Pour finir, notez que la boucle commence à l’indice 1 et termine à l’indice NF (pour Number of Fields) inclus puisque $0 est l’argument entier et que $1 à $n correspondent aux morceaux de l’argument découpé selon FS.

Publicités

Raspberry Pi, WiFi, ssh et ligne de commande

J’ai rebranché mon vieux Raspberry Pi pour les besoins de geekeries personnelles. J’ai vu qu’il existait une version Lite de Raspbian et j’ai choisi de l’utiliser car mon Raspberry Pi n’est pas de première jeunesse et ma carte SD ne fait que 4 Go. J’ai eu une petite surprise en démarrant le système : il n’y a pas de serveur X. Il faut donc tout faire en ligne de commande. Challenged accepted!

Démarrer le Raspberry Pi

Raspbian Lite est téléchargeable sur le site de la fondation Raspberry. La version actuelle est Jessie. Je me suis aidé de deux articles que j’avais écrit il y a déjà longtemps pour créer ma carte SD avec l’image du système. J’ai branché mon clavier, ma télé, l’alimentation et j’ai obtenu prompt.

Changer le layout du clavier

Parce que qu’un système qwerty quand on a un clavier azerty c’est pas sympa, surtout si on a besoin d’utiliser des symboles, j’ai commencé par passer en azerty. Internet vous propose plusieurs techniques, j’ai utilisée celle-ci :

sudo dpkg-reconfigure keyboard-configuration

La configuration est intuitive avec une interface type ncurse. Quand c’est terminé, il suffit de redémarrer avec la commande reboot.

Configuration du WiFi

Aucune difficulté à ce que Raspbian reconnaisse mon dongle WiFi. Je l’ai branché et il est directement apparu comme wlan0 quand j’ai appelé la commande ifconfig. La partie un peu moins fun est la configuration du réseau WiFi (SSID + passphrase). La fondation Raspberry propose un tutoriel pour cela. Je crois avoir eu besoin de redémarrer à nouveau pour que ça fonctionne (en plus de la procédure expliquée dans le lien).

Configuration IP manuelle

En général, le serveur DHCP de votre box assignera toujours la même IP à votre Raspberry Pi. Il est quand même plus prudent de lui affecter une adresse IP fixe pour le retrouver facilement. Idéalement, il faudrait aussi demander à votre box de ne plus attribuer cette adresse IP par DHCP…

J’ai tout d’abord regardé quelle était mon adresse actuelle, quel masque de sous-réseau était utilisé et quelle était l’adresse de la gateway :

$ ifconfig wlan0
wlan0     Link encap:Ethernet  HWaddr 74:da:38:5d:fc:6b  
          inet addr:192.168.1.17  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: 2a01:cb05:8980:9400:944d:6692:7db0:9552/64 Scope:Global
          inet6 addr: fe80::9d35:79ba:e404:4253/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14436 errors:0 dropped:400 overruns:0 frame:0
          TX packets:4818 errors:0 dropped:1 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:17129734 (16.3 MiB)  TX bytes:701974 (685.5 KiB)
$ ip route
default via 192.168.1.1 dev wlan0  metric 303 
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.17  metric 303

J’ai ensuite modifié le fichier /etc/network/interfaces de manière adaptée :

cat /etc/network/interfaces
[...]

allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.1.17
    netmask 255.255.255.0
    gateway 192.168.1.1
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

[...]

Activation de ssh

La dernière étape pour que mon système puisse être headless était d’activer le serveur SSH et ainsi pouvoir me connecter depuis mon ordinateur de bureau. La fondation Raspberry explique comment faire ceci dans ce tutoriel. Avec Raspbian Lite, il suffit de créer un fichier ayant pour nom ssh, à la racine de la carte SD. J’ai donc éteint mon Raspberry Pi et j’ai inséré ma carte mémoire dans mon Mac et j’ai utilisé le terminal :

$ cd /Volumes/boot/
$ touch ssh

Une fois le Raspberry Pi redémarré, vous pouvez regarder si le serveur SSH est démarré avec la commande suivante :

ps -eaf | grep ssh

Si vous un brin plus optimiste, vous pouvez essayé directement depuis votre PC :

$ ping 192.168.1.17
PING 192.168.1.17 (192.168.1.17): 56 data bytes
64 bytes from 192.168.1.17: icmp_seq=0 ttl=64 time=18.548 ms
64 bytes from 192.168.1.17: icmp_seq=1 ttl=64 time=6.127 ms
^C
--- 192.168.1.17 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 6.127/12.337/18.548/6.211 ms
imac-de-pierre:/ pierregradot$ ssh pi@192.168.1.17
The authenticity of host '192.168.1.17 (192.168.1.17)' can't be established.
ECDSA key fingerprint is SHA256:xv5CB0epvX+e8sKhgLFp2bP+1jzU8j7PzGAVAnZs8q4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.17' (ECDSA) to the list of known hosts.
pi@192.168.1.17's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Apr  3 16:22:55 2017
pi@raspberrypi:~ $ echo "Hell yeah!"
Hell yeah!
pi@raspberrypi:~ $ 

Et voilà ! J’ai débranché le Raspberry Pi de la télé, j’ai rangé mon clavier, et c’était bon !

PS : en fait, si vous avez un câble Ethernet, vous pouvez vous passer d’un clavier et d’une télé. Voici comment faire : Headless Raspberry Pi Setup.

 

 


XBee et XCTU sous Linux

Cela doit bien faire 2 ans que deux modules XBee (des Pro S1 de chez Digi) traînent dans mes tiroirs et je n’en avais rien fait. Ayant pour projet de faire des capteurs de température et d’humidité sans fil, je me suis dit que c’était le bon moment de les utiliser. L’idée est d’envoyer les données à un Raspberry Pi pour traitement. J’ai donc pris mon XBee Explrer Dongle, j’y ai connecté un module Xbee et je l’ai branché à mon PC. Digi fournit un logiciel pour gérer les modules XBee connectés à un PC, les configurer, envoyer et recevoir des données : il s’agit de XCTU. De nombreux tutoriels sur Internet disent que XCTU n’est disponible que sous Windows mais cette époque est révolue ! Vous pouvez télécharger les différentes versions pour Windows, Linux et Mac ici.

Installation et lancement

Si vous êtes sous Linux et que vous ne savez pas si vous devez opter pour la version 32 ou la version 64 bits, il vous suffit de taper la commande uname -a pour savoir si vous avez un processeur 32 ou 64 bits. Exemple dans mon cas :

~$ uname -a
Linux pgradot-xubuntu 4.4.0-53-generic #74-Ubuntu SMP 
Fri Dec 2 15:58:04 UTC 2016 i686 i686 i686 GNU/Linux

Le i686 m’indique que mon processeur est 32 bits.

Une fois le téléchargement terminé, rendez le fichier exécutable et lancez-le avec les droits administrateurs :

$ chmod u+x 40002880_G.run
$ sudo ./40002880_G.run

Un wizard vous guide dans l’installation de XCTU. Par défaut, le logiciel s’installe dans /opt/Digi où un sous-dossier XCTU-NG est créé. On y trouve launcher et app (le premier lançant le second). Si vous lancez l’un des deux sans les droits administrateurs, cela ne fera qu’ouvrir une petite fenêtre qui ne contient rien et que vous ne pourrez pas fermer… Ayez le réflexe sudo, ça marchera beaucoup mieux ! Vous verrez alors ceci :

xbee 1 startup

Ajout de modules

Vous pouvez ajouter des modules radios ou les découvrir en cliquant que les icônes en haut à gauche. L’ info-bulle vous avait sans doute déjà fait deviner le mode opératoire. Le mien étant branché via un dongle USB, il apparaît comme étant /dev/ttyUSB0 :

xbee 2 add device

XCTU récupère et affiche tout la configuration du nouveau module :

xbee 3 device added

Onglets configuration, console et réseau

XCTU est intuitif et l’info-bulle de droite nous dit qu’il existe 3 onglets, chacun correspondant à un mode :

  1. Le mode configuration, ouvert par défaut, permet de voir la configuration des modules comme montré précédemment mais aussi de la modifier et d’envoyer la nouvelle configuration au module.
  2. Le monde console permet soit d’interagir via des commandes AT avec un module, soit d’envoyer des paquets sur le réseau. Vous pouvez enregistrer des paquets et jouer des séquences d’envoi. Certainement très pratique pour des tests.
  3. Le mode réseau, pour avoir un aperçu de la topologie du réseau sans fil à portée.

Commandes AT

Si vous souhaitez envoyez des commandes AT à votre module, il suffit d’aller dans l’onglet console et d’appuyer sur le bouton Open (qui se transforme en bouton Close, visible en vert dans l’image ci-dessous). Vous tapez alors +++ dans à gauche, vous attendez une seconde et le module répond OK pour indiquer qu’il est bien passé en mode commande. Tapez alors vos commandes en les terminant par entrée et le module vous répondra. Sans activité de votre part pendant 3 secondes, le module sort automatiquement et silencieusement du mode commande et l’envoi d’une nouvelle commande sera alors sans réponse. Sparkun a écrit un très bon aide-mémoire pour les commandes AT disponibles.

xbee 4 at

Pour aller plus loin

Exploring XBees and XCTU par Sparkun


Utiliser Linux pour lire un disque Time Machine

OS X propose le très pratique Time Machine pour sauvegarder ses données automatiquement sur un disque dur externe. Presque en même temps que mon iMac, j’ai acheté un disque dur externe sur lequel je sauvegarde régulièrement l’intégralité de mon disque interne. Il y a quelques jours, mon iMac m’a lâché et ne s’allume plus. Je vais l’emmener voir le docteur mais en attendant j’ai besoin de certains fichiers importants. Il s’avère que ces fichiers sont sur mon disque Time Machine car je fais régulièrement mes sauvegardes 🙂

Je n’ai pas de deuxième Mac pour lire ce disque mais j’ai plein d’autres PC, avec Windows ou Linux. Petit hic : Time Machine utilise des disques au format HFS+. Windows ne comprend pas ce format par défaut, il faut utiliser des logiciels additionnels ; en revanche, Linux le comprend très bien car il est directement supporté par le noyau. J’ai donc ressorti un vieux PC portable et, malgré une vieille version de Mint, j’ai immédiatement pu accéder à mes fichiers !

time machine linux1

Il y a un second hic : Time Machine stocke les sauvegardes de manière un peu ésotériques, à grands coups de liens, et cela mène à des problèmes de permissions empêchant l’accès aux fichiers de mon user. Comme par hasard, les fichiers que je veux sont là-dedans…

time machine linux 2

Je ne suis bien sûr pas le premier à rencontrer cette difficulté, d’autres se sont déjà penchés sérieusement sur le sujet et un gentil développeur a publié sur Github un script pour copier une arborescence d’un disque Time Machine vers un dossier local. Ça fait un peu mal pour récupérer beaucoup de données, mais on ne va pas se plaindre et remercier le monsieur, Marcello Barnaba !

J’ai donc copié mon dossier $HOME/Documents vers mon PC Linux :

$ sudo ./copy-from-time-machine.sh "/media/Seagate Backup Plus Drive/Backups.backupdb/iMac de pierregradot/2016-03-05-112442/iMac/Users/pierregradot/Documents" ./time_restored/

Mes fichiers étaient là, mission accomplie 🙂


update-alternatives

Hier, j’ai voulu installé Eclipse sous Xubuntu avec le nouvel installateur Oomph. Au lancement de l’installateur, j’ai eu un message d’erreur car je ne disposais que de Java 7 et que l’installateur avait besoin de Java 8. Je me suis alors dit qu’il était temps de mettre en oeuvre la technique des update-alternatives dont m’avait parlé mon administrateur système préféré.

État des lieux de Java

Tout d’abord, commençons par regarder ce vers quoi pointe la commande java :

$ ls -la $(which java)
 lrwxrwxrwx 1 root root 22 sept. 20 19:05 /usr/bin/java -> /etc/alternatives/java

Le principe d’update-alternatives est de ne pas faire de lien direct vers la vraie implémentation mais un lien vers une alternative, qui est dans /etc/alternatives qui pointe à son tour vers le programme réellement chargé de la commande. Regardons les alternatives connues du système des alternatives pour java :

$ update-alternatives --list java
/usr/lib/jvm/java-7-openjdk-i386/jre/bin/java

Il n’y a pour l’instant qu’un seul programme connu pour la commande java et c’est sans surprise un Java 7.

Installation d’une nouvelle alternative pour Java

Personnellement, j’ai choisi d’utiliser le JDK 8 d’Oracle et j’ai récupéré la dernière version disponible sur le site officiel. J’ai décompressé l’archive tar.gz dans /usr/local :

$ ls
bin/ etc/ games/ include/ jdk1.8.0_60/ lib/ man@ sbin/ share/ src/

Pour installer une nouvelle alternative, il faut utiliser une ligne de commande de la forme suivante :

update-alternatives --install <link> <name> <path> <priority>

<link> est l’endroit où placer le lien qui pointera vers /etc/alternatives, <name> est la commande pour laquelle on installe une alternative et <path> est le chemin vers le programme concret. <priority> sert pour les groupes de liens et quand le mode automatique est utilisé. Plus la priorité est élevée, plus l’alternative aura une priorité forte. Pour installer une nouvelle alternative vers mon JDK 8, j’ai utilisé la commande suivante :

$ sudo update-alternatives --install /usr/bin/java java
    /usr/local/jdk1.8.0_60/bin/java 3000
update-alternatives: using /usr/local/jdk1.8.0_60/bin/java 
    to provide /usr/bin/java (java) in auto mode

C’est maintenant Java 8 qui est utilisé par défaut car la nouvelle alternative a une priorité plus forte que l’alternative déjà disponible :

$ which java
/usr/bin/java
pgradot@pgradot-xubuntu:~$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) Client VM (build 25.60-b23, mixed mode)

A titre d’exemple, voici ce qui se passe pour une installation avec une priorité à 1000 au lieu de 3000 :

$ sudo update-alternatives --install /usr/bin/java java
    /usr/local/jdk1.8.0_60/bin/java 1000
pgradot@pgradot-xubuntu:~/Documents/git/PyTweet$ java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
OpenJDK Client VM (build 24.79-b02, mixed mode, sharing)

Changer d’alternative

Il est simple de passer d’une alternative à une autre et il est donc pratique de garder plusieurs versions installées sur le système et de changer la cible concrète de la commande au besoin. Cela est utile quand un projet particulier réclame une version différente que la version utilisée généralement, que ce soit Java ou autre.

On commence par lister les alternatives pour la commande souhaitée :

$ sudo update-alternatives --list java
[sudo] password for pgradot:
/usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
/usr/local/jdk1.8.0_60/bin/java

Il suffit ensuite d’utiliser la commande --set :

$ sudo update-alternatives --set java
    /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
update-alternatives: using /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
    to provide /usr/bin/java (java) in manual mode
$ java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
OpenJDK Client VM (build 24.79-b02, mixed mode, sharing)

Il est pratique de lister les alternatives avant d’utiliser --set pour pouvoir copier-coller le chemin souhaité. Il n’est pas possible d’utiliser un programme qui n’a pas encore été ajouté comme alternative :

$ sudo update-alternatives --set java /usr/local/jdk1.8.0_60/bin/jav
update-alternatives: error: alternative /usr/local/jdk1.8.0_60/bin/jav
    for java not registered; not setting

L’erreur dit bien que l’alternative n’est pas connue et non que le programme n’existe pas.

Supprimer une alternative

Rien de bien compliqué pour supprimer une alternative. Si c’est l’alternative est actuellement utilisé, le gestionnaire des alternatives se rabat sur une autre alternative en se basant sur les priorités :

$ sudo update-alternatives --remove java /usr/local/jdk1.8.0_60/bin/java
update-alternatives: removing manually selected
    alternative - switching java to auto mode
update-alternatives: using /usr/lib/jvm/java-7-openjdk-i386/jre/bin/java
    to provide /usr/bin/java (java) in auto mode

C’est aussi l’un des avantages du système des alternatives. Il sera charge de mettre à jour les différents liens quand des alternatives sont modifiées.