Web services Ligne de commande

Thèmes : TERMINAL / CONSOLE / LIGNE DE COMMANDE / SCRIPTING

Sources: https.linuxfr.org

Publié le 05.07.2019
« Internet est cassé » ou plutôt : comment tester du TCP ou de l’UDP

N. D. L. A. : cet article est généré via une commande du type ansible-playbook InternetEstCassé.yml pour tester réellement les commandes.

Internet est cassé. Le Web ne marche plus. Le réseau est pété. Ça marche pas. Ce site est indisponible. Des lutins bloquent ma connexion. Les tuyaux sont bouchés. Y a Firefox qui veut pas, etc. Quand il y a un souci de réseau, toutes sortes d’imprécations, de suppositions, de supplications ou de raisons sont lancées. Peut‐on aller plus loin et essayer d’y voir plus clair, de déboguer un peu le souci et d’identifier le problème.

On va parler un peu d'IP — surtout la version 4 —, de TCP, d’UDP, d’ICMP, d’ARP, de DNS, de HTTP, etc., d’un peu de vue pratique de vérification du bon fonctionnement ou de recherche d’un souci. En dehors des pages Wikipédia, une lecture utile : la RFC 1180 « A TCP/IP Tutorial » (avec une traduction en français disponible).

    Sommaire

    Tester un flux TCP ou UDP

    TL;DR : En TCP on va avoir des réponses de type connexion refusée si le port est fermé ou filtré avec rejet, une attente ou un délai d’attente trop long si le trafic est poubellisé, et une connexion établie si tout va bien. En UDP, on sera notifié d’une erreur en cas de port fermé ou filtré avec rejet, et ne saura pas différencier un port ouvert d’une « poubellisation » du trafic. Il y a plein d’outils possibles pour tester un flux TCP ou UDP en client ou en serveur.

    Prenons un cas simple : on sait si l’on utilise du TCP ou de l’UDP, et l’on veut joindre un port précis sur une adresse IP donnée.

    Port TCP

    Port TCP fermé

    Commençons par essayer de joindre un port fermé (rien en écoute, le programme qui devait écouter dessus n’a pas été lancé, a mal démarré, écoute sur une autre adresse ou port, une autre version d’IP, a déjà planté, etc.). Dans cet exemple, on veut joindre l’adresse IP 127.0.0.1 et le port TCP 60001, avec ce que l’on a sous la main (souvent sur un serveur, le choix des outils disponibles est limité). On constate des réponses de type connexion refusée.

    $ telnet 127.0.0.1 60001
        (durée d'exécution 00:00)
    Trying 127.0.0.1...telnet: Unable to connect to remote host: Connection refused
        (code de retour 1)
    
    $ nc -t -v 127.0.0.1 60001
        (durée d'exécution 00:00)
    nc: connect to 127.0.0.1 port 60001 (tcp) failed: Connection refused
        (code de retour 1)
    
    $ bash -c exec 3<>/dev/tcp/127.0.0.1/60001
        (durée d'exécution 00:00)
    bash: connect: Connexion refusée
    bash: /dev/tcp/127.0.0.1/60001: Connexion refusée
        (code de retour 1)
    
    $ zsh -c autoload -U tcp_open;tcp_open 127.0.0.1 60001
        (durée d'exécution 00:00)
    tcp_open:ztcp:174: connection failed: connexion refusée
        (code de retour 1)
    
    $ nmap -v -sT -p 60001 127.0.0.1
        (durée d'exécution 00:00)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:06 CEST
    Initiating Ping Scan at 19:06
    Scanning 127.0.0.1 [2 ports]
    Completed Ping Scan at 19:06, 0.00s elapsed (1 total hosts)
    Initiating Connect Scan at 19:06
    Scanning localhost (127.0.0.1) [1 port]
    Completed Connect Scan at 19:06, 0.00s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up (0.00011s latency).
    
    PORT      STATE  SERVICE
    60001/tcp closed unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds
        (code de retour 0)
    
    $ sudo traceroute -T -N 1 -m 1 -q 1 -p 60001 127.0.0.1 -O info
        (durée d'exécution 00:00)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  localhost (127.0.0.1) <rst,ack>  0.033 ms
        (code de retour 0)
    
    $ openssl s_client -connect 127.0.0.1:60001
        (durée d'exécution 00:00)
    140595570463872:error:0200206F:system library:connect:Connection refused:../crypto/bio/b_sock2.c:110:
    140595570463872:error:2008A067:BIO routines:BIO_connect:connect error:../crypto/bio/b_sock2.c:111:
    connect:errno=111
        (code de retour 1)
    
    $ ssh -p 60001 127.0.0.1
        (durée d'exécution 00:00)
    Pseudo-terminal will not be allocated because stdin is not a terminal.
    ssh: connect to host 127.0.0.1 port 60001: Connection refused
        (code de retour 255)
    
    $ perl -e use IO::Socket::INET;new IO::Socket::INET ( PeerHost => "127.0.0.1", PeerPort => "60001", Proto => "tcp",) or die "ERROR in Socket Creation : $!\n";
        (durée d'exécution 00:00)
    ERROR in Socket Creation : Connection refused
        (code de retour 111)
    
    $ python3 -c import socket;socket.socket().connect(("127.0.0.1",60001))
        (durée d'exécution 00:00)
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ConnectionRefusedError: [Errno 111] Connection refused
        (code de retour 1)
    
    $ ruby -e require "socket";s = TCPSocket.open("127.0.0.1", 60001)
        (durée d'exécution 00:00)
    -e:1:in `initialize': Connection refused - connect(2) for "127.0.0.1" port 60001 (Errno::ECONNREFUSED)
        from -e:1:in `open'
        from -e:1:in `<main>'
        (code de retour 1)
    
    $ curl -v -s --max-time 60 http://127.0.0.1:60001
        (durée d'exécution 00:00)
    * Expire in 0 ms for 6 (transfer 0x55bf2d3fec40)
    * Expire in 60000 ms for 8 (transfer 0x55bf2d3fec40)
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Expire in 200 ms for 4 (transfer 0x55bf2d3fec40)
    * connect to 127.0.0.1 port 60001 failed: Connexion refusée
    * Failed to connect to 127.0.0.1 port 60001: Connexion refusée
    * Closing connection 0
        (code de retour 7)
    
    $ wget --timeout=60 --tries=1 http://127.0.0.1:60001
        (durée d'exécution 00:00)
    --2019-06-30 19:06:05--  http://127.0.0.1:60001/
    Connexion à 127.0.0.1:60001… échec : Connexion refusée.
        (code de retour 4)
    
    $ links -dump http://127.0.0.1:60001
        (durée d'exécution 00:00)
    Connection refused
        (code de retour 1)
    
    $ chromium http://127.0.0.1:60001
       (Ce site est inaccessible. 127.0.0.1 n'autorise pas la connexion.  ERR_CONNECTION_REFUSED)
    $ firefox http://127.0.0.1:60001
       (Unable to connect Firefox can’t establish a connection to the server at 127.0.0.1:60001)
    

    Port TCP filtré avec rejet

    Essayons de joindre un port TCP filtré avec rejet par un pare‐feu. Dans cet exemple, on veut joindre l’adresse IP 127.0.0.1 et le port TCP 60000 (et l’on va obtenir exactement le même résultat que précédemment, à part pour nmap).

    $ telnet 127.0.0.1 60000
       (durée d'exécution 0:00:01.015323)
    Trying 127.0.0.1...telnet: Unable to connect to remote host: Connection refused
        (code de retour 1)
    
    $ nc -t -v 127.0.0.1 60000
       (durée d'exécution 0:00:01.012197)
    nc: connect to 127.0.0.1 port 60000 (tcp) failed: Connection refused
        (code de retour 1)
    
    $ bash -c exec 3<>/dev/tcp/127.0.0.1/60000
       (durée d'exécution 0:00:01.006805)
    bash: connect: Connexion refusée
    bash: /dev/tcp/127.0.0.1/60000: Connexion refusée
        (code de retour 1)
    
    $ zsh -c autoload -U tcp_open;tcp_open 127.0.0.1 60000
       (durée d'exécution 0:00:01.026754)
    tcp_open:ztcp:174: connection failed: connexion refusée
        (code de retour 1)
    
    $ nmap -v -sT -p 60000 127.0.0.1
       (durée d'exécution 0:00:00.277299)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:06 CEST
    Initiating Ping Scan at 19:06
    Scanning 127.0.0.1 [2 ports]
    Completed Ping Scan at 19:06, 0.00s elapsed (1 total hosts)
    Initiating Connect Scan at 19:06
    Scanning localhost (127.0.0.1) [1 port]
    Completed Connect Scan at 19:06, 0.20s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up (0.00012s latency).
    
    PORT      STATE    SERVICE
    60000/tcp filtered unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 0.26 seconds
        (code de retour 0)
    
    $ sudo traceroute -T -N 1 -m 1 -q 1 -p 60000 127.0.0.1 -O info
       (durée d'exécution 0:00:00.019657)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  localhost (127.0.0.1)  0.030 ms
        (code de retour 0)
    
    $ openssl s_client -connect 127.0.0.1:60000
       (durée d'exécution 0:00:01.042588)
    140296376857728:error:0200206F:system library:connect:Connection refused:../crypto/bio/b_sock2.c:110:
    140296376857728:error:2008A067:BIO routines:BIO_connect:connect error:../crypto/bio/b_sock2.c:111:
    connect:errno=111
        (code de retour 1)
    
    $ ssh -p 60000 127.0.0.1
       (durée d'exécution 0:00:01.022311)
    Pseudo-terminal will not be allocated because stdin is not a terminal.
    ssh: connect to host 127.0.0.1 port 60000: Connection refused
        (code de retour 255)
    
    $ perl -e use IO::Socket::INET;new IO::Socket::INET ( PeerHost => "127.0.0.1", PeerPort => "60000", Proto => "tcp",) or die "ERROR in Socket Creation : $!\n";
       (durée d'exécution 0:00:01.052922)
    ERROR in Socket Creation : Connection refused
        (code de retour 111)
    
    $ python3 -c import socket;socket.socket().connect(("127.0.0.1",60000))
       (durée d'exécution 0:00:01.077612)
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ConnectionRefusedError: [Errno 111] Connection refused
        (code de retour 1)
    
    $ ruby -e require "socket";s = TCPSocket.open("127.0.0.1", 60000)
       (durée d'exécution 0:00:01.178000)
    -e:1:in `initialize': Connection refused - connect(2) for "127.0.0.1" port 60000 (Errno::ECONNREFUSED)
        from -e:1:in `open'
        from -e:1:in `<main>'
        (code de retour 1)
    
    $ curl -v -s --max-time 60 http://127.0.0.1:60000
       (durée d'exécution 0:00:01.038146)
    * Expire in 0 ms for 6 (transfer 0x55d959531c40)
    * Expire in 60000 ms for 8 (transfer 0x55d959531c40)
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Expire in 200 ms for 4 (transfer 0x55d959531c40)
    * connect to 127.0.0.1 port 60000 failed: Connexion refusée
    * Failed to connect to 127.0.0.1 port 60000: Connexion refusée
    * Closing connection 0
        (code de retour 7)
    
    $ wget --timeout=60 --tries=1 http://127.0.0.1:60000
       (durée d'exécution 0:00:01.031294)
    --2019-06-30 19:06:20--  http://127.0.0.1:60000/
    Connexion à 127.0.0.1:60000… échec : Connexion refusée.
        (code de retour 4)
    
    $ links -dump http://127.0.0.1:60000
       (durée d'exécution 0:00:03.066049)
    Connection refused
        (code de retour 1)
    
    $ chromium http://127.0.0.1:60000
       (Ce site est inaccessible. 127.0.0.1 n'autorise pas la connexion.  ERR_CONNECTION_REFUSED)
    $ firefox http://127.0.0.1:60000
       (Unable to connect Firefox can’t establish a connection to the server at 127.0.0.1:60000)
    

    Port TCP filtré avec poubellisation

    Maintenant tentons de joindre un port TCP filtré avec poubellisation des paquets par un pare‐feu. Dans cet exemple, on veut joindre l’adresse IP 127.0.0.1 et le port TCP 60020. Les résultats obtenus sont de type délai d’attente trop long, en l’absence de réponse.

    $ telnet 127.0.0.1 60020
        (durée d'exécution 0:02:10.315065)
    Trying 127.0.0.1...telnet: Unable to connect to remote host: Connection timed out
        (code de retour 1)
    
    $ nc -t -v 127.0.0.1 60020
        (durée d'exécution 0:02:10.256818)
    nc: connect to 127.0.0.1 port 60020 (tcp) failed: Connection timed out
        (code de retour 1)
    
    $ bash -c exec 3<>/dev/tcp/127.0.0.1/60020
        (durée d'exécution 0:02:09.811710)
    bash: connect: Connexion terminée par expiration du délai d'attente
    bash: /dev/tcp/127.0.0.1/60020: Connexion terminée par expiration du délai d'attente
        (code de retour 1)
    
    $ zsh -c autoload -U tcp_open;tcp_open 127.0.0.1 60020
        (durée d'exécution 0:02:10.423479)
    tcp_open:ztcp:174: connection failed: connexion terminée par expiration du délai d'attente
        (code de retour 1)
    
    $ nmap -v -sT -p 60020 127.0.0.1
        (durée d'exécution 0:00:00.860462)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:15 CEST
    Initiating Ping Scan at 19:15
    Scanning 127.0.0.1 [2 ports]
    Completed Ping Scan at 19:15, 0.00s elapsed (1 total hosts)
    Initiating Connect Scan at 19:15
    Scanning localhost (127.0.0.1) [1 port]
    Completed Connect Scan at 19:15, 0.20s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up (0.00012s latency).
    
    PORT      STATE    SERVICE
    60020/tcp filtered unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 0.39 seconds
        (code de retour 0)
    
    $ sudo traceroute -T -N 1 -m 1 -q 1 -p 60020 127.0.0.1 -O info
        (durée d'exécution 0:00:05.126178)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  *
        (code de retour 0)
    
    $ openssl s_client -connect 127.0.0.1:60020
        (durée d'exécution 0:02:11.242094)
    140029672752256:error:0200206E:system library:connect:Connection timed out:../crypto/bio/b_sock2.c:110:
    140029672752256:error:2008A067:BIO routines:BIO_connect:connect error:../crypto/bio/b_sock2.c:111:
    connect:errno=110
        (code de retour 1)
    
    $ ssh -p 60020 127.0.0.1
        (durée d'exécution 0:02:10.451898)
    Pseudo-terminal will not be allocated because stdin is not a terminal.
    ssh: connect to host 127.0.0.1 port 60020: Connection timed out
        (code de retour 255)
    
    $ perl -e use IO::Socket::INET;new IO::Socket::INET ( PeerHost => "127.0.0.1", PeerPort => "60020", Proto => "tcp",) or die "ERROR in Socket Creation : $!\n";
        (durée d'exécution 0:02:10.522130)
    ERROR in Socket Creation : Connection timed out
        (code de retour 110)
    
    $ python3 -c import socket;socket.socket().connect(("127.0.0.1",60020))
        (durée d'exécution 0:02:10.415526)
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    TimeoutError: [Errno 110] Connection timed out
        (code de retour 1)
    
    $ ruby -e require "socket";s = TCPSocket.open("127.0.0.1", 60020)
        (durée d'exécution 0:02:10.149211)
    -e:1:in `initialize': Connection timed out - connect(2) for "127.0.0.1" port 60020 (Errno::ETIMEDOUT)
        from -e:1:in `open'
        from -e:1:in `<main>'
        (code de retour 1)
    
    $ curl -v -s --max-time 60 http://127.0.0.1:60020
        (durée d'exécution 0:01:00.105772)
    * Expire in 0 ms for 6 (transfer 0x556c2510fc40)
    * Expire in 60000 ms for 8 (transfer 0x556c2510fc40)
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Expire in 200 ms for 4 (transfer 0x556c2510fc40)
    * Connection timed out after 60000 milliseconds
    * Closing connection 0
        (code de retour 28)
    
    $ wget --timeout=60 --tries=1 http://127.0.0.1:60020
        (durée d'exécution 0:01:00.365540)
    --2019-06-30 19:27:14--  http://127.0.0.1:60020/
    Connexion à 127.0.0.1:60020… échec : Connexion terminée par expiration du délai d'attente.
    Abandon.
        (code de retour 4)
    
    $ links -dump http://127.0.0.1:60020
        (durée d'exécution 0:06:32.165744)
    Connection timed out
        (code de retour 1)
    
    $ chromium http://127.0.0.1:60020
       (Ce site est inaccessible. 127.0.0.1 a mis trop de temps à répondre. ERR_CONNECTION_TIMED_OUT) 
    $ firefox http://127.0.0.1:60020
       (The connection has timed out. The server at 127.0.0.1 is taking too long to respond.
    

    Port TCP en écoute

    Au fait, ça donne quoi des connexions TCP réussies ? Dans notre exemple, la connexion est réussie, mais le serveur ne parle pas forcément le bon protocole, et de toute façon il coupe la connexion.

    $ telnet 127.0.0.1 60040
        (durée d'exécution 0:00:00.109715)
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.Connection closed by foreign host.
        (code de retour 1)
    
    $ nc -t -v 127.0.0.1 60040
        (durée d'exécution 0:00:00.072833)
    Connection to 127.0.0.1 60040 port [tcp/*] succeeded!
        (code de retour 0)
    
    $ bash -c exec 3<>/dev/tcp/127.0.0.1/60040
        (durée d'exécution 0:00:00.077887)
    
        (code de retour 0)
    
    $ zsh -c autoload -U tcp_open;tcp_open 127.0.0.1 60040
        (durée d'exécution 0:00:00.582218)
    Session 1 (host 127.0.0.1, port 60040 fd 3) opened OK.
    Setting default TCP session 1
        (code de retour 0)
    
    $ nmap -v -sT -p 60040 127.0.0.1
        (durée d'exécution 0:00:00.575144)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:34 CEST
    Initiating Ping Scan at 19:34
    Scanning 127.0.0.1 [2 ports]
    Completed Ping Scan at 19:34, 0.00s elapsed (1 total hosts)
    Initiating Connect Scan at 19:34
    Scanning localhost (127.0.0.1) [1 port]
    Discovered open port 60040/tcp on 127.0.0.1
    Completed Connect Scan at 19:34, 0.00s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up (0.0022s latency).
    
    PORT      STATE SERVICE
    60040/tcp open  unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 0.21 seconds
        (code de retour 0)
    
    $ sudo traceroute -T -N 1 -m 1 -q 1 -p 60040 127.0.0.1 -O info
        (durée d'exécution 0:07:30.000489)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  localhost (127.0.0.1) <syn,ack>  0.097 ms
        (code de retour 0)
    
    $ openssl s_client -connect 127.0.0.1:60040
        (durée d'exécution 0:00:00.123910)
    CONNECTED(00000003)
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 0 bytes and written 283 bytes
    Verification: OK
    ---
    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    Early data was not sent
    Verify return code: 0 (ok)
    ---write:errno=104
        (code de retour 1)
    
    $ ssh -p 60040 127.0.0.1
        (durée d'exécution 0:00:00.210452)
    Pseudo-terminal will not be allocated because stdin is not a terminal.
    ssh_exchange_identification: Connection closed by remote host
        (code de retour 255)
    
    $ perl -e use IO::Socket::INET;new IO::Socket::INET ( PeerHost => "127.0.0.1", PeerPort => "60040", Proto => "tcp",) or die "ERROR in Socket Creation : $!\n";
        (durée d'exécution 0:00:01.093543)
    
        (code de retour 0)
    
    $ python3 -c import socket;socket.socket().connect(("127.0.0.1",60040))
        (durée d'exécution 0:00:00.156651)
    
        (code de retour 0)
    
    $ ruby -e require "socket";s = TCPSocket.open("127.0.0.1", 60040)
        (durée d'exécution 0:00:01.445306)
    
        (code de retour 0)
    
    $ curl -v -s --max-time 60 http://127.0.0.1:60040
        (durée d'exécution 0:00:00.182162)
    * Expire in 0 ms for 6 (transfer 0x55ebb4398c40)
    * Expire in 60000 ms for 8 (transfer 0x55ebb4398c40)
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Expire in 200 ms for 4 (transfer 0x55ebb4398c40)
    * Connected to 127.0.0.1 (127.0.0.1) port 60040 (#0)
    > GET / HTTP/1.1
    > Host: 127.0.0.1:60040
    > User-Agent: curl/7.64.0
    > Accept: */*
    > 
    * Empty reply from server
    * Connection #0 to host 127.0.0.1 left intact
        (code de retour 52)
    
    $ wget --timeout=60 --tries=1 http://127.0.0.1:60040
        (durée d'exécution 0:00:00.215817)
    --2019-06-30 19:42:33--  http://127.0.0.1:60040/
    Connexion à 127.0.0.1:60040… connecté.
    requête HTTP transmise, en attente de la réponse… Erreur de lecture (Connexion ré-initialisée par le correspondant) dans les en-têtes.
    Abandon.
        (code de retour 4)
    
    $ links -dump http://127.0.0.1:60040
        (durée d'exécution 0:00:00.214406)
    Error reading from socket
        (code de retour 1)
    
    $ chromium http://127.0.0.1:60040
       (Ce site est inaccessible. Il se peut que la page Web à l'adresse http://127.0.0.1:60040/ soit temporairement inaccessible ou qu'elle ait été déplacée de façon permanente à une autre adresse Web.  ERR_SOCKET_NOT_CONNECTED)
    
    $ firefox http://127.0.0.1:60040
       (The connection was reset. The connection to the server was reset while the page was loading.)
    

    Trafic réseau

    Jetons un œil au trafic réseau échangé (si le port est fermé, la réponse est un TCP RST ; si le trafic est rejeté, la réponse est un « ICMP port inaccessible » ; si le trafic est poubellisé, le TCP SYN (et les réessais) restent sans réponse ; enfin, si le port est ouvert, la connexion s’établit avec la poignée de main TCP, la fermeture de session pouvant être différente suivant si des données ont été envoyées ou non). Ici, source et destination sont une seule et même machine, mais peu importe.

    $ sudo tshark -i lo -f "host 127.0.0.1 and (tcp or icmp)"
    Running as user "root" and group "root". This could be dangerous.
    tshark: Lua: Error during loading:
     [string "/usr/share/wireshark/init.lua"]:44: dofile has been disabled due to running Wireshark as superuser. See https://wiki.wireshark.org/CaptureSetup/CapturePrivileges for help in running Wireshark as an unprivileged user.
    Capturing on 'Loopback'
    (n° paquet, horloge, source -> destination  protocole...)
        1 0.000000000    127.0.0.1 → 127.0.0.1    TCP 74 39766 → 60001 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=10596677 TSecr=0 WS=128
        2 0.000016574    127.0.0.1 → 127.0.0.1    TCP 54 60001 → 39766 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
    (...)
       37 8.190159737    127.0.0.1 → 127.0.0.1    TCP 74 42694 → 60000 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=10598724 TSecr=0 WS=128
       38 8.190177891    127.0.0.1 → 127.0.0.1    ICMP 102 Destination unreachable (Port unreachable)
       39 9.190192177    127.0.0.1 → 127.0.0.1    TCP 74 [TCP Retransmission] 42694 → 60000 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=10598975 TSecr=0 WS=128
       40 9.190276171    127.0.0.1 → 127.0.0.1    ICMP 102 Destination unreachable (Port unreachable)
    (...)
      103 28.328151130    127.0.0.1 → 127.0.0.1    TCP 74 51006 → 60020 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=10603759 TSecr=0 WS=128
      104 29.326198277    127.0.0.1 → 127.0.0.1    TCP 74 [TCP Retransmission] 51006 → 60020 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=10604009 TSecr=0 WS=128
      105 31.330178795    127.0.0.1 → 127.0.0.1    TCP 74 [TCP Retransmission] 51006 → 60020 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=10604510 TSecr=0 WS=128
    (...)
      207 1683.477081380    127.0.0.1 → 127.0.0.1    TCP 74 45876 → 60040 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=11017546 TSecr=0 WS=128
      208 1683.477103411    127.0.0.1 → 127.0.0.1    TCP 74 60040 → 45876 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=11017546 TSecr=11017546 WS=128
      209 1683.477118197    127.0.0.1 → 127.0.0.1    TCP 66 45876 → 60040 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=11017546 TSecr=11017546
      210 1683.477172642    127.0.0.1 → 127.0.0.1    TCP 66 60040 → 45876 [FIN, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=11017546 TSecr=11017546
      211 1683.477299723    127.0.0.1 → 127.0.0.1    TCP 66 45876 → 60040 [FIN, ACK] Seq=1 Ack=2 Win=43776 Len=0 TSval=11017546 TSecr=11017546
      212 1683.477307741    127.0.0.1 → 127.0.0.1    TCP 66 60040 → 45876 [ACK] Seq=2 Ack=2 Win=43776 Len=0 TSval=11017546 TSecr=11017546
    (...)
      276 1688.854649280    127.0.0.1 → 127.0.0.1    TCP 66 45900 → 60040 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=11018891 TSecr=11018891
      277 1688.854689131    127.0.0.1 → 127.0.0.1    TCP 66 60040 → 45900 [FIN, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=11018891 TSecr=11018891
      278 1688.854759615    127.0.0.1 → 127.0.0.1    HTTP 145 GET / HTTP/1.1 
      279 1688.854773879    127.0.0.1 → 127.0.0.1    TCP 54 60040 → 45900 [RST] Seq=2 Win=0 Len=0
    

    Port UDP

    Port UDP fermé

    Et si l’on teste de l’UDP, lorsque rien n’est en écoute, par exemple, on peut détecter que le port est fermé (globalement le client est notifié de la fermeture).

    $ sh -c echo coin|nc -u -v -w10 127.0.0.1 60011
        (durée d'exécution 0:00:00.009070)
    
        (code de retour 1)
    
    $ bash -c exec 3<>/dev/udp/127.0.0.1/60011; echo coin >&3; sleep 10
        (durée d'exécution 0:00:10.011074)
    
        (code de retour 0)
    
    $ traceroute -U -N 1 -m 1 -q 1 -p 60011 127.0.0.1
        (durée d'exécution 0:00:00.030841)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  localhost (127.0.0.1)  0.039 ms
        (code de retour 0)
    
    $ sudo nmap -v -sU -p 60011 127.0.0.1
        (durée d'exécution 0:00:00.519691)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:42 CEST
    Initiating UDP Scan at 19:42
    Scanning localhost (127.0.0.1) [1 port]
    Completed UDP Scan at 19:42, 0.24s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up (0.000090s latency).
    
    PORT      STATE  SERVICE
    60011/udp closed unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 0.44 seconds
               Raw packets sent: 1 (28B) | Rcvd: 2 (84B)
        (code de retour 0)
    
    

    Port UDP filtré avec rejet

    Ou que le trafic est rejeté par un pare‐feu, cela revient plus ou moins au même :

    $ sh -c echo coin|nc -u -v -w10 127.0.0.1 60010
        (durée d'exécution 0:00:00.027297)
    
        (code de retour 1)
    
    $ bash -c exec 3<>/dev/udp/127.0.0.1/60010; echo coin >&3; sleep 10
        (durée d'exécution 0:00:10.010258)
    
        (code de retour 0)
    
    $ traceroute -U -N 1 -m 1 -q 1 -p 60010 127.0.0.1
        (durée d'exécution 0:00:00.015655)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  localhost (127.0.0.1)  0.035 ms
        (code de retour 0)
    
    $ sudo nmap -v -sU -p 60010 127.0.0.1
        (durée d'exécution 0:00:00.392441)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:43 CEST
    Initiating UDP Scan at 19:43
    Scanning localhost (127.0.0.1) [1 port]
    Completed UDP Scan at 19:43, 0.22s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up (0.000081s latency).
    
    PORT      STATE  SERVICE
    60010/udp closed unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 0.33 seconds
               Raw packets sent: 1 (28B) | Rcvd: 2 (84B)
        (code de retour 0)
    
    

    Port UDP filtré avec poubellisation

    En revanche, il est devient difficile de différencier le trafic UDP poubellisé du trafic réussi (car le client n’est pas notifié de l’erreur, le protocole UDP n’est pas connecté et ne garantit ni livraison, ni l’ordre d’arrivée, ni la non‐duplication des paquets transmis).

    $ sh -c echo coin|nc -u -v -w10 127.0.0.1 60030
        (durée d'exécution 0:00:20.026213)
    Connection to 127.0.0.1 60030 port [udp/*] succeeded!
        (code de retour 0)
    
    $ bash -c exec 3<>/dev/udp/127.0.0.1/60030; echo coin >&3; sleep 10
        (durée d'exécution 0:00:10.010664)
    
        (code de retour 0)
    
    $ traceroute -U -N 1 -m 1 -q 1 -p 60030 127.0.0.1
        (durée d'exécution 0:00:05.016796)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  *
        (code de retour 0)
    
    $ sudo nmap -v -sU -p 60030 127.0.0.1
        (durée d'exécution 0:00:02.354541)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:43 CEST
    Initiating UDP Scan at 19:43
    Scanning localhost (127.0.0.1) [1 port]
    Completed UDP Scan at 19:43, 2.04s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up.
    
    PORT      STATE         SERVICE
    60030/udp open|filtered unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 2.23 seconds
               Raw packets sent: 2 (56B) | Rcvd: 2 (56B)
        (code de retour 0)
    
    

    Port UDP en écoute

    On retrouve le même résultat sur un test avec effectivement un serveur en écoute :

    $ sh -c echo coin|nc -u -v -w10 127.0.0.1 60050
        (durée d'exécution 0:00:20.029595)
    Connection to 127.0.0.1 60050 port [udp/*] succeeded!
        (code de retour 0)
    
    $ bash -c exec 3<>/dev/udp/127.0.0.1/60050; echo coin >&3; sleep 10
        (durée d'exécution 0:00:10.015239)
    
        (code de retour 0)
    
    $ traceroute -U -N 1 -m 1 -q 1 -p 60050 127.0.0.1
        (durée d'exécution 0:00:05.020411)
    traceroute to 127.0.0.1 (127.0.0.1), 1 hops max, 60 byte packets
     1  *
        (code de retour 0)
    
    $ sudo nmap -v -sU -p 60050 127.0.0.1
        (durée d'exécution 0:00:02.302030)
    Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-30 19:44 CEST
    Initiating UDP Scan at 19:44
    Scanning localhost (127.0.0.1) [1 port]
    Completed UDP Scan at 19:44, 2.03s elapsed (1 total ports)
    Nmap scan report for localhost (127.0.0.1)
    Host is up.
    
    PORT      STATE         SERVICE
    60050/udp open|filtered unknown
    
    Read data files from: /usr/bin/../share/nmap
    Nmap done: 1 IP address (1 host up) scanned in 2.18 seconds
               Raw packets sent: 2 (56B) | Rcvd: 2 (56B)
        (code de retour 0)
    
    

    Trafic échangé

    Regardons le trafic réseau échangé (un port fermé ou un trafic rejeté génère une réponse « ICMP port inaccessible », et un port ouvert ou un trafic poubellisé ne génère aucune réponse). Ici source et destination sont une seule et même machine, mais peu importe.

    $ sudo tshark -i lo -f "host 127.0.0.1 and (udp or icmp)"
    Running as user "root" and group "root". This could be dangerous.
    tshark: Lua: Error during loading:
     [string "/usr/share/wireshark/init.lua"]:44: dofile has been disabled due to running Wireshark as superuser. See https://wiki.wireshark.org/CaptureSetup/CapturePrivileges for help in running Wireshark as an unprivileged user.
    Capturing on 'Loopback'
    (n° paquet, horloge, source -> destination  protocole...)
        1 0.000000000    127.0.0.1 → 127.0.0.1    UDP 43 58991 → 60011 Len=1
        2 0.000018701    127.0.0.1 → 127.0.0.1    ICMP 71 Destination unreachable (Port unreachable)
    (...)
        9 15.846541876    127.0.0.1 → 127.0.0.1    UDP 43 52810 → 60010 Len=1
       10 15.846560153    127.0.0.1 → 127.0.0.1    ICMP 71 Destination unreachable (Port unreachable)
    (...)
       17 31.086988181    127.0.0.1 → 127.0.0.1    UDP 43 48647 → 60030 Len=1
       18 31.086997796    127.0.0.1 → 127.0.0.1    UDP 43 48647 → 60030 Len=1
       19 32.087088785    127.0.0.1 → 127.0.0.1    UDP 43 48647 → 60030 Len=1
    (...)
       34 73.221725214    127.0.0.1 → 127.0.0.1    UDP 43 46294 → 60050 Len=1
       35 73.221740517    127.0.0.1 → 127.0.0.1    UDP 43 46294 → 60050 Len=1
       36 74.221835792    127.0.0.1 → 127.0.0.1    UDP 43 46294 → 60050 Len=1
    

    TODO : des idées pour la suite

    Des idées pour la suite :

    Commentaires : voir le flux atom ouvrir dans le navigateur

     


     

    Publié le 31.03.2019
    Bogue, fonctionnalité, mauvais usage ? Un cas pratique

    Dans la rétrospective LinuxFr.org de la première quinzaine de mars 2019, il était question de la réponse surprenante de diff : « Le fichier /var/lib/lxc/alpha/rootfs/dev/full est un fichier spécial‐caractères alors que le fichier /var/lib/lxc/beta/rootfs/dev/full est un fichier spécial‐caractères. »

    Les choses auraient pu en rester là. Mais quand même, ça reste une bonne occasion de se demander si c’est un bogue, une fonctionnalité ou un mauvais usage, non ? Jouons un peu avec ce cas pratique.

      Sommaire

      De quels fichiers parlions‐nous ?

      $ ls -l /var/lib/lxc/alpha/rootfs/dev/full /var/lib/lxc/beta/rootfs/dev/full
      crw-rw-rw- 1 root root 1, 7 mars   4  2011 /var/lib/lxc/alpha/rootfs/dev/full
      crw-rw-rw- 1 root root 1, 7 oct.  21  2017 /var/lib/lxc/beta/rootfs/dev/full

      Il s’agit donc de fichiers spéciaux en mode caractère (le c au début de la ligne), ayant pour majeur 1 et pour mineur 7. Ce type de fichiers peut être créé avec la commande mknod (paquet coreutils chez Debian, logiciel tiré du projet GNU coreutils).

      Et le binaire /usr/bin/diff provenait du paquet Debian Stretch diffutils 1:3.5-3, également tiré du projet GNU diffutils.

      $ diff --version
      diff (GNU diffutils) 3.5
      

      Reproduire le problème

      D’abord créons un petit labo pour reproduire :

      $ mkdir dir1 dir2
      $ sudo mknod dir1/file c 1 7
      $ sudo mknod dir2/file c 1 7
      $ ls -l dir*/file
      crw-r--r-- 1 root root 1, 7 mars  28 17:43 dir1/file
      crw-r--r-- 1 root root 1, 7 mars  28 17:43 dir2/file
      $ diff -r dir1 dir2
      Le fichier dir1/file est un fichier spécial-caractères alors que le fichier dir2/file est un fichier spécial-caractères
      

      OK, c’est reproduit, ça arrive (au moins) sur la comparaison récursive entre deux répertoires contenant chacun un fichier spécial en mode caractère avec même majeur, même mineur, même nom.

      Un problème de traduction ?

      Un effet de la langue ? Il s’agit peut‐être juste d’une erreur de traduction en français ?

      $ export LC_ALL=C
      $ export LANG=C
      $ diff -r dir1 dir2
      File dir1/file is a character special file while file dir2/file is a character special file

      Pas mieux en anglais. Et d’ailleurs ce n’est pas mieux avec diffutils 1:3.7-2 de Debian Sid, en sachant que la 3.7 est la dernière version publiée par le projet GNU.

      Avant de continuer à creuser, notons que la comparaison directe des deux fichiers est une mauvaise idée :

      $ diff dir1/file dir2/file
      (ne rend pas la main)
      

      Débogage

      Par curiosité un coup d’œil avec l’outil de débogage (sous GNU/Linux) strace (logiciel venant de strace.io) pour voir les appels système utilisés par un programme et les signaux reçus :

      $ strace -f diff dir1/file dir2/file
      …
      stat("dir1/file", {st_mode=S_IFCHR|0644, st_rdev=makedev(0x1, 0x7), ...}) = 0
      stat("dir2/file", {st_mode=S_IFCHR|0644, st_rdev=makedev(0x1, 0x7), ...}) = 0
      openat(AT_FDCWD, "dir1/file", O_RDONLY) = 3
      openat(AT_FDCWD, "dir2/file", O_RDONLY) = 4
      read(3, "(que des NUL)"..., 4096) = 4096
      read(4, "(que des NUL)"..., 4096) = 4096
      read(3, "(que des NUL)"..., 4096) = 4096
      read(4, "(que des NUL)"..., 4096) = 4096
      …
      

      Comme on peut lire en boucle sur ces fichiers, ça peut durer longtemps…

      En revanche, on peut essayer sur la version récursive sur les deux répertoires :

      $ strace -f diff -r dir1 dir2
      …
      stat("dir1/file", {st_mode=S_IFCHR|0644, st_rdev=makedev(0x1, 0x7), ...}) = 0
      stat("dir2/file", {st_mode=S_IFCHR|0644, st_rdev=makedev(0x1, 0x7), ...}) = 0
      fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0x3), ...}) = 0
      write(1, "File dir1/file is a character sp"..., 92File dir1/file is a character special file while file dir2/file is a character special file
      ) = 92
      …
      

      OK, il n’a pas l’air de pousser la comparaison bien loin… On regarde les attributs des deux fichiers, ce sont des fichiers spéciaux, alors on sort la phrase peu explicative.

      Les sources

      Et si on regardait les sources du paquet Debian ?

      $ apt source diffutils
      $ cd diffutils-3.7/
      

      La traduction ?

      $ grep -1 "character special file" ./po/fr.po
      #: lib/file-type.c:69
      msgid "character special file"
      msgstr "fichier spécial-caractères"
      --
      #: lib/file-type.c:84
      msgid "multiplexed character special file"
      msgstr "fichier spécial avec des caractères multiplexés"
      

      Le premier cas est celui qui nous intéresse. On retrouve bien les lignes attendues côté code en excluant les fichiers de traduction :

      $ grep -nr "character special file" .|grep -v "/po/"
      ./lib/file-type.c:69:    return _("character special file");
      ./lib/file-type.c:84:    return _("multiplexed character special file");
      

      Il s’agit en gros d’une fonction file_type qui écrit « character special file » ou sa traduction lorsqu’elle croise un fichier spécial de type caractère.

      Reste à trouver d’où vient le reste de la phrase :

      $ grep -2 while po/fr.po
      #: src/diff.c:1337 src/diff.c:1387
      #, c-format
      msgid "File %s is a %s while file %s is a %s\n"
      msgstr "Le fichier %s est un %s alors que le fichier %s est un %s\n"
      

      Visiblement une phrase générique prévue pour dire « ah, flûte, dommage, le premier fichier est un machin, tandis que le second est un bidule », sauf qu’ici machin == bidule (ici on sourit légèrement parce qu’on va aller voir la ligne 1 337 de diff.c, et que c’est l33t).

      Le code

      La portion de code concernée :

        {
          /* We have two files that are not to be compared.  */
      
          /* See POSIX 1003.1-2001 for this format.  */
          message5 ("File %s is a %s while file %s is a %s\n",
              file_label[0] ? file_label[0] : cmp.file[0].name,
              file_type (&cmp.file[0].stat),
              file_label[1] ? file_label[1] : cmp.file[1].name,
              file_type (&cmp.file[1].stat));
      
          /* This is a difference.  */
          status = EXIT_FAILURE;
        }

      En gros, on est dans une zone concernant les fichiers non comparables, alors on affiche le message à base de machin et de bidule sans se poser la question du cas machin == bidule.

      Le même code est utilisé ligne 1387, mais il semble plus pertinent, d’après le commentaire qui précise que l’un des fichiers est un lien symbolique et l’autre non, donc ici machin != bidule.

        {
          /* We have two files that are not to be compared, because
             one of them is a symbolic link and the other one is not.  */
      
          message5 ("File %s is a %s while file %s is a %s\n",
              file_label[0] ? file_label[0] : cmp.file[0].name,
              file_type (&cmp.file[0].stat),
              file_label[1] ? file_label[1] : cmp.file[1].name,
              file_type (&cmp.file[1].stat));
      
          /* This is a difference.  */
          status = EXIT_FAILURE;
        }

      Tout laisse à penser que nous sommes en présence d’un bogue, ou en tout cas d’une imprécision dans la réponse fournie à l’utilisateur : la réponse sera toujours la même lorsque l’on compare deux fichiers spéciaux‐caractères, indépendamment de leurs majeur et mineur d’ailleurs, et le fait qu’ils soient différents (le but de diff donc) est seulement sous‐entendu, par le fait que le message apparaît (il n’y aurait pas de tel message sur deux fichiers comparables identiques).

      Et avec un autre diff ?

      Le commentaire côté GNU « See POSIX 1003.1-2001 for this format » pourrait laisser penser qu’il s’agit d’une contrainte de la norme POSIX. Mais sous FreeBSD diff se comporte différemment :

      $ mkdir t1 t2
      $ mkfifo t1/toto 
      $ mkfifo t2/toto 
      $ diff -r t1 t2
      File t1/toto is not a regular file or directory and was skipped

      Le BSD diff bloque aussi sur la comparaison entre les deux fichiers. Mais le message est donc plus explicite lorsqu’il s’agit d’une comparaison de deux répertoires.

      De la sorte, ce comportement est tel que défini par l’open Group :

      « If both file1 and file2 are directories, diff shall not compare block special files, character special files, or FIFO special files to any files and shall not compare regular files to directories. Further details are as specified in Diff Directory Comparison Format. The behavior of diff on other file types is implementation‐defined when found in directories. »

      Si file1 et file2 sont des répertoires, diff ne devrait pas entreprendre la comparaison des fichiers spéciaux de type blocs ou caractères ou les tubes nommés (FIFO) à n’importe quel autre fichier ni comparer un fichier à un répertoire.

      Ouvrir des bogues ?

      Passons à l’étape suivante, récupérer le code source directement du projet en amont et soumettre une proposition de correction ? Cette partie est laissée à l’attention du lecteur.

      $ git clone https://git.savannah.gnu.org/git/diffutils.git
      

      ou https://svnweb.freebsd.org/base/release/12.0.0/usr.bin/diff/.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 23.08.2018
      Dark Moon : une distribution GNU/Cygwin portable pour Windows

      Dark Moon est un émulateur de terminal open source développé par Mehdi Boutayeb Ferkatou, étudiant à l'université Paul Sabatier, et édité par MBK logiciel dans sa version UWP sur le Microsoft Store.

      Dark-Moon

      Dark Moon est à ce jour la seule distribution GNU/Cygwin disponible sur le Microsoft Store et sur le site de l’éditeur.

      Sommaire

      Présentation

      Dark Moon est un ensemble de logiciels libres basé sur Cygwin rendu portable permettant l’exécution de commandes POSIX dans le but d’émuler un environnement UNIX sur plate‐forme Windows x64. Dark Moon permet de créer des scripts et des programmes utilisant les commandes grâce à une grande collection d’outils GNU et open source intégrée dans le terminal.

      Embarquer une collection d’API POSIX sous la forme d’un exécutable nous permet d’envisager une informatique hyper‐transportable pour les émulateurs et distributions GNU/Cygwin, il suffit alors de trouver du courant et un processeur hôte pour exécuter l’application, ce qui aurait été auparavant impossible avant la naissance de Dark Moon. L’objectif technique recherché est de fournir un environnement de développement ainsi qu’un émulateur UNIX cloisonnés dans un exécutable apportant une mobilité au logiciel, permettant d’exécuter l’application sur n’importe quel système Windows.

      Idée générale

      Dark Moon est autonome, ce qui le distingue d’autres distributions équivalentes. Il est possible d’exécuter des commandes Shell et Bash ainsi que de créer et exécuter des scripts sur la console. L’application est également un outil de développement, notamment en offrant aux utilisateurs un environnement de développement libre tel que GCC.

      Cette distribution est également un outil UNIX complet, personnalisable et offrant une mobilité ne demandant pas d’installation préalable. Elle est née en vue de fournir aux utilisateurs des possibilités étendues en complément de l’interpréteur de commande Windows. Il est possible de manipuler des fichiers ainsi que la ruche de registre sans déposer aucune empreinte sur l’ordinateur hôte, afin d’éviter d’apporter des modifications durables à un poste utilisé temporairement.

      L’émulateur a fait l’objet d’une ouverture au public du code source, le logiciel libre est sous licence GNU GPL, il n’y a donc pas de restriction d’utilisation et de modification du logiciel tant que les conditions de la licence sont respectées.

      En comparaison d’autres distributions Cygwin et GNU/Linux, l’application ne requiert aucun composant externe, les fichiers étant cloisonnés dans l’exécutable même, permettant un emploi à partir d’un stockage amovible comme une clé USB.

      Différentes bibliothèques ont été incluses, notamment MinGW qui travaille avec des composants Windows comme la bibliothèque MSVCRT liée à Microsoft Visual C++. Busybox est intégré pour l’implémentation d’un grand nombre des commandes. Par ailleurs, il est également possible d’utiliser un agent d’authentification OpenSSH.

      Le code source ainsi que les fichiers compilés ont été emballés dans l’exécutable pour respecter le concept de portabilité (il suffit de l’extraire avec 7zip pour avoir accès aux fichiers sources).

      Liste des commandes actuellement disponibles

      Voi job_spec [&]                            history [-c] [-d offset] [n] or hist>
       (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
       . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
       :                                       kill [-s sigspec | -n signum | -sigs>
       [ arg... ]                              let arg [arg ...]
       [[ expression ]]                        local [option] name[=value] ...
       alias [-p] [name[=value] ... ]          logout [n]
       bg [job_spec ...]                       mapfile [-d delim] [-n count] [-O or>
       bind [-lpsvPSVX] [-m keymap] [-f file>  popd [-n] [+N | -N]
       break [n]                               printf [-v var] format [arguments]
       builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
       caller [expr]                           pwd [-LP]
       case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
       cd [-L|[-P [-e]] [-@]] [dir]            readarray [-n count] [-O origin] [-s>
       command [-pVv] command [arg ...]        readonly [-aAf] [name[=value] ...] o>
       compgen [-abcdefgjksuv] [-o option] [>  return [n]
       complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
       compopt [-o|+o option] [-DE] [name ..>  set [-abefhkmnptuvxBCHP] [-o option->
       continue [n]                            shift [n]
       coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
       declare [-aAfFgilnrtux] [-p] [name[=v>  source filename [arguments]
       dirs [-clpv] [+N] [-N]                  suspend [-f]
       disown [-h] [-ar] [jobspec ... | pid >  test [expr]
       echo [-neE] [arg ...]                   time [-p] pipeline
       enable [-a] [-dnps] [-f filename] [na>  times
       eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
       exec [-cl] [-a name] [command [argume>  true
       exit [n]                                type [-afptP] name [name ...]
       export [-fn] [name[=value] ...] or ex>  typeset [-aAfFgilnrtux] [-p] name[=v>
       false                                   ulimit [-SHabcdefiklmnpqrstuvxPT] [l>
       fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
       fg [job_spec]                           unalias [-a] name [name ...]
       for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [-n] [name ...]
       for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
       function name { COMMANDS ; } or name >  variables - Names and meanings of so>
       getopts optstring name [arg]            wait [-n] [id ...]
       hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
       help [-dms] [pattern ...]               { COMMANDS ; }
      Voi job_spec [&]                            history [-c] [-d offset] [n] or hist>
       (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
       . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
       :                                       kill [-s sigspec | -n signum | -sigs>
       [ arg... ]                              let arg [arg ...]
       [[ expression ]]                        local [option] name[=value] ...
       alias [-p] [name[=value] ... ]          logout [n]
       bg [job_spec ...]                       mapfile [-d delim] [-n count] [-O or>
       bind [-lpsvPSVX] [-m keymap] [-f file>  popd [-n] [+N | -N]
       break [n]                               printf [-v var] format [arguments]
       builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
       caller [expr]                           pwd [-LP]
       case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
       cd [-L|[-P [-e]] [-@]] [dir]            readarray [-n count] [-O origin] [-s>
       command [-pVv] command [arg ...]        readonly [-aAf] [name[=value] ...] o>
       compgen [-abcdefgjksuv] [-o option] [>  return [n]
       complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
       compopt [-o|+o option] [-DE] [name ..>  set [-abefhkmnptuvxBCHP] [-o option->
       continue [n]                            shift [n]
       coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
       declare [-aAfFgilnrtux] [-p] [name[=v>  source filename [arguments]
       dirs [-clpv] [+N] [-N]                  suspend [-f]
       disown [-h] [-ar] [jobspec ... | pid >  test [expr]
       echo [-neE] [arg ...]                   time [-p] pipeline
       enable [-a] [-dnps] [-f filename] [na>  times
       eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
       exec [-cl] [-a name] [command [argume>  true
       exit [n]                                type [-afptP] name [name ...]
       export [-fn] [name[=value] ...] or ex>  typeset [-aAfFgilnrtux] [-p] name[=v>
       false                                   ulimit [-SHabcdefiklmnpqrstuvxPT] [l>
       fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
       fg [job_spec]                           unalias [-a] name [name ...]
       for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [-n] [name ...]
       for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
       function name { COMMANDS ; } or name >  variables - Names and meanings of so>
       getopts optstring name [arg]            wait [-n] [id ...]
       hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
       help [-dms] [pattern ...]               { COMMANDS ; }
      Voi job_spec [&]                            history [-c] [-d offset] [n] or hist>
       (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
       . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
       :                                       kill [-s sigspec | -n signum | -sigs>
       [ arg... ]                              let arg [arg ...]
       [[ expression ]]                        local [option] name[=value] ...
       alias [-p] [name[=value] ... ]          logout [n]
       bg [job_spec ...]                       mapfile [-d delim] [-n count] [-O or>
       bind [-lpsvPSVX] [-m keymap] [-f file>  popd [-n] [+N | -N]
       break [n]                               printf [-v var] format [arguments]
       builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
       caller [expr]                           pwd [-LP]
       case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
       cd [-L|[-P [-e]] [-@]] [dir]            readarray [-n count] [-O origin] [-s>
       command [-pVv] command [arg ...]        readonly [-aAf] [name[=value] ...] o>
       compgen [-abcdefgjksuv] [-o option] [>  return [n]
       complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
       compopt [-o|+o option] [-DE] [name ..>  set [-abefhkmnptuvxBCHP] [-o option->
       continue [n]                            shift [n]
       coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
       declare [-aAfFgilnrtux] [-p] [name[=v>  source filename [arguments]
       dirs [-clpv] [+N] [-N]                  suspend [-f]
       disown [-h] [-ar] [jobspec ... | pid >  test [expr]
       echo [-neE] [arg ...]                   time [-p] pipeline
       enable [-a] [-dnps] [-f filename] [na>  times
       eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
       exec [-cl] [-a name] [command [argume>  true
       exit [n]                                type [-afptP] name [name ...]
       export [-fn] [name[=value] ...] or ex>  typeset [-aAfFgilnrtux] [-p] name[=v>
       false                                   ulimit [-SHabcdefiklmnpqrstuvxPT] [l>
       fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
       fg [job_spec]                           unalias [-a] name [name ...]
       for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [-n] [name ...]
       for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
       function name { COMMANDS ; } or name >  variables - Names and meanings of so>
       getopts optstring name [arg]            wait [-n] [id ...]
       hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
       help [-dms] [pattern ...]               { COMMANDS ; }

      Syntaxe

      Avec les appliquettes de commande mises à disposition, il est possible de créer des scripts aisément, comme présenté ci‐dessous :

      #Mon premier script
      function() 
      {
        local variableLocal="function 1"
        echo "$variableLocal"
        echo "Nombres de paramètres : $#"
        echo $1
        echo $2
      }
      
      function "Hello" "World"

      Pour lancer le script, placez‐vous dans le dossier contenant le script (obligatoire) :

      cd C:\Users\[Userprofile]\Documents\script-Shell

      Faites un chmod :

      chmod 700 MonPremierScript

      Et exécutez‐le :

      Nombres de paramètres : 2
      Hello 
      World

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 02.08.2018
      Présentation de The Log File Navigator

      The Log File Navigator, ou lnav en plus court, est un outil en ligne de commande pour afficher des journaux, sous licence BSD. Par rapport aux classiques cat, grep ou less, il propose quelques fonctionnalités supplémentaires :

      • il offre de la coloration syntaxique ;
      • il permet d’afficher plusieurs journaux en même temps, les lignes étant triées en fonction de la date et de l’heure à laquelle l’événement est survenu (c’est pratique pour corréler des informations entre plusieurs processus) ;
      • il offre différents modes d’affichage.

      Capture d’écran de lnav

      Lnav est un outil en ligne de commande qui permet de consulter des fichiers de journaux et de naviguer dedans, le tout dans un terminal. Il sait reconnaître différents formats de journaux (syslog, Common Web Access Log, qui est utilisé par Apache et nginx, strace, Java Logs, etc.). Cela lui permet de proposer de la coloration syntaxique sur les éléments reconnus et de trier par date d’événement les différentes lignes des journaux.

      Il sait ouvrir des fichiers compressés (gzip et bzip2 notamment) et suivre un journal actif (à la façon d’un tail -f). Il est également possible d’utiliser des filtres (pour ignorer certains messages, à la grep -v) et de réaliser des recherches pour mettre en avant une expression. À noter : il est possible d’utiliser <Tab> lorsque l’on saisit une expression, pour avoir une auto‐complétion en fonction du contenu des journaux. Les raccourcis clavier sont classiques (par exemple, g pour aller au début du fichier et G pour aller à la fin, ou encore / pour lancer une recherche, comme dans less, notamment).

      A priori, il serait aussi possible de jouer avec les journaux via des requêtes SQL. Un système de sessions permet également de conserver certaines informations d’une exécution à l’autre (les filtres par exemple). Enfin, petit plus, la barre à droite permet de voir rapidement à quels endroits du ou des fichiers il y a eu des lignes d’erreurs ou des lignes qui correspondent à la recherche en cours.

      Au final, il est appréciable de pouvoir utiliser lnav en retrouvant la plupart des réflexes issus des outils classiques, mais avec la coloration syntaxique en plus. Pouvoir corréler simplement des informations provenant de plusieurs fichiers est également très pratique. Pour les fonctionnalités plus avancées, ça viendra peut‐être plus tard.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 09.04.2018
      Trois outils pour développeur : MailHog, Tokei et Pandoc

      Dans cette dépêche, je vais vous présenter trois outils que j’utilise de temps en temps et qui pourraient servir à d’autres développeurs :

      • MailHog permet d’attraper des courriels pour les examiner ;
      • Tokei compte les lignes de code d’un projet ;
      • Pandoc est un couteau suisse pour manipuler des fichiers et les transformer d’un langage de balisage à un autre.

      MailHog

      MailHog (sous licence MIT) permet d’attraper des courriels envoyés par une plate‐forme de développement et de les afficher dans une interface Web. Pour cela, il fournit un serveur SMTP et un remplaçant au binaire sendmail, libre à vous de choisir le moyen qui vous convient le mieux. Il offre également, en option, la possibilité de transférer vers un vrai serveur SMTP les courriels et un outil de type chaos-monkey pour tester les cas d’erreurs d’envoi de courriels.

      L’interface Web de MailHog avec trois courriels capturés

      Je m’en sers quand je développe sur la partie serveur de Cozy Cloud. Cela permet de tester des fonctionnalités qui nécessitent l’envoi de courriels sans avoir à se compliquer la vie à configurer un vrai serveur d’envoi de courriels. En bonus, on évite de prendre le risque d’envoyer des courriels vers de vrais comptes d’autres personnes et on ne perd pas de temps à attendre que le courriel arrive, en attente d’un traitement anti‐pourriel.


      Tokei

      Pour estimer la taille d’un projet, le nombre de lignes de code peut être une métrique intéressante. Il existe plusieurs projets pour faire ça, celui que je trouve le plus pratique est Tokei (sous licence Apache ou MIT). Voici ce qu’il affiche pour le dépôt principal de code de LinuxFr.org :

      -------------------------------------------------------------------------------
       Language            Files        Lines         Code     Comments       Blanks
      -------------------------------------------------------------------------------
       CoffeeScript           10          770          642           31           97
       Dockerfile              1           70           49            4           17
       HTML                   24         2660         2161            4          495
       JavaScript             11         2686         2025          394          267
       Markdown                1          187          187            0            0
       Rakefile                2           33           24            3            6
       Ruby                  262        11593         8338         1500         1755
       Ruby HTML               1           47           46            0            1
       Sass                   47        27317        23467         1583         2267
       Shell                   4           68           50            4           14
       SVG                    41        10886        10865           17            4
       TeX                     1           53           43            0           10
       Plain Text             44          531          531            0            0
       XML                     1           11           11            0            0
       YAML                    4          173          160            4            9
      -------------------------------------------------------------------------------
       Total                 454        57085        48599         3544         4942
      -------------------------------------------------------------------------------

      Par rapport à cloc, Tokei a plusieurs avantages :

      • il est beaucoup plus rapide (0,03 seconde pour Tokei contre 3,2 secondes pour cloc sur le dépôt principal de LinuxFr.org) ;
      • il est plus précis : cloc utilise des expressions rationnelles, alors que Tokei a de vrais analyseurs (en particulier, un début de commentaire dans une chaîne de caractères comme printf("/*") peut bien induire en erreur cloc) ;
      • il ignore par défaut les fichiers listés dans .gitignore (par exemple, quand j’ai lancé cloc sur l’exemple ci‐dessus, il a compté les fichiers dans tmp/cache et j’ai dû le relancer avec des options pour qu’il fasse ce que j’en attendais).

      Pandoc

      Il existe de nombreux langages de balisage : HTML, Markdown, reStructuredText, textile, DocBook, \LaTeX, MediaWiki markup, OrgMode, EPUB, etc. Et ces langages ont parfois plusieurs variantes (exemple : CommonMark et GitHub Flavored Markdown pour le Markdown). Bref, ce n’est pas toujours facile de connaître les différents langages et de passer de l’un à l’autre. Pandoc (sous licence GPL v2 ou plus) permet de convertir un texte de la plupart de ces langages vers un autre langage, ou d’autres choses comme du PDF ou de l’OpenDocument.

      Je m’en sers, par exemple, pour écrire des présentations en Markdown et en générer une version PDF via la classe Beamer pour \LaTeX. Ça m’a également servi, par le passé, pour convertir un wiki d’un format à un autre.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 19.03.2018
      Des alternatives à grep, ls et find

      Les outils en ligne de commande comme ls, grep et find existent depuis de nombreuses années et, même s’ils continuent de s’améliorer, il est parfois intéressant de regarder les alternatives. Je vais vous parler de ripgrep, exa et fd.

      Ripgrep

      Les alternatives à grep ne manquent pas. Déjà, la commande grep de son shell peut être soit le grep du projet GNU ou celui du projet BSD. Il y a aussi le grep intégré à Git. Et d’autres outils sont apparus ces dernières années, citons ack-grep, ag (the silver searcher), pt (the platinum searcher) et le petit dernier ripgrep.

      Ces outils se battent pour savoir lequel est le plus rapide ou a le plus de fonctionnalités. Personnellement, j’utilise ripgrep car il est très rapide, réalise par défaut une recherche récursive dans les répertoires (un gros manque de GNU grep selon moi, mais c’est probablement bien trop tard pour changer le comportement de GNU grep), a une présentation par défaut des résultats que j’apprécie, et il sait chercher dans des fichiers compressés (gzip, bzip2, xz) avec l’option -z.

      Exa

      Lister des fichiers est un besoin de base dans un terminal et ls remplit bien ce besoin. Exa est une alternative à ls que j’utilise pour ses couleurs, qui viennent par défaut et que je trouve plus agréables que celles de ls. Il propose également une vue arborescente des répertoires et fichiers, qui remplace plutôt tree. Exa est aussi capable d’afficher le statut Git des fichiers et répertoires.

      Fd

      Fd peut remplacer avantageusement find. Je n’utilise que très peu l’un ou l’autre, mais fd a une syntaxe plus facile à retenir et il est, d’après ses tests, plus rapide que find. Il utilise par défaut l’encodage UTF-8, il a une sortie colorée et ignore les fichiers listés dans un .gitignore. Et surtout, ça fait deux fois moins de caractères à taper pour le nom de la commande. ;-)

      Les points communs

      Vitesse

      On retrouve beaucoup de benchmarks autour de ces outils, les performances sont un vrai enjeu. Mettre trois secondes au lieu de quinze secondes peut paraître anecdotique pour des recherches un peu compliquées, mais cette différence peut casser le rythme : si une commande prend plus de dix secondes, je vais sûrement commencer à aller voir ailleurs.

      Fonctionnalités et comportement par défaut

      Ces outils ont beaucoup de fonctionnalités : les options que l’on peut passer en ligne de commande permettent de changer fortement leurs comportements. Ceci dit, en pratique, je n’utilise que peu d’options (et quasiment toujours les mêmes). En revanche, j’apprécie beaucoup que ces outils cherchent à avoir le comportement par défaut le plus utile.

      Intégration avec Git

      Ces outils ont tous une intégration avec Git : ripgrep et fd savent lire les fichiers .gitignore et exa sait afficher l’état Git des fichiers. Ce n’est pas un critère très important à mes yeux car je suis à l’aise avec Git en ligne de commande. Mais c’est intéressant de noter à quel point git est devenu incontournable en ligne de commande.

      Rust

      Un fait remarquable est que les trois outils présentés sont écrits en Rust. Il faut croire que ce langage convient bien pour écrire des outils en ligne de commande. C’est un domaine où le temps d’exécution est important (quand on lance une commande, c’est appréciable que le retour soit instantané ou en tout cas très rapide). Les langages de script (JavaScript, Ruby, Python) ont un temps de lancement de leur machine virtuelle qui peut casser cette impression de vitesse, je comprends donc que les développeurs d’outils en ligne de commande puissent s’en éloigner. En revanche, il est plus surprenant de ne pas retrouver d’outils en Go, en D, en OCaml ou en Haskell. Peut‐être que les lecteurs de LinuxFr.org auront une explication à cela.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 23.04.2018
      Quel terminal pour 2018 ?

      Vous connaissez les terminaux, ces petites fenêtres le plus souvent noires où l’on tape des lignes de commande bizarres ? Eh bien, vous risquez d’être surpris : le choix du logiciel pour faire ça n’est pas aussi simple que ça en a l’air et des gens continuent de proposer de nouvelles alternatives. Cette dépêche vise à présenter rapidement quelques fonctionnalités intéressantes que les terminaux historiques ne géraient pas forcément et à présenter quelques terminaux.

      Sommaire

      Les fonctionnalités

      Apparence et polices

      Historiquement, les terminaux avaient une couleur pour le texte et une autre pour le fond. Si l’on s’en tient à ce siècle, les terminaux étaient principalement en 16 couleurs au début, puis certains terminaux ont commencé à gérer des palettes de couleur plus étendues (256 couleurs par exemple) et, aujourd’hui, certains terminaux savent manipuler des couleurs sur 24 bits.

      De même, les terminaux utilisaient surtout des jeux de caractères où un caractère était codé sur un octet, mais la prise en charge d’Unicode est maintenant répandue. Il faut néanmoins se méfier, certains terminaux annoncent gérer l’Unicode mais ne savent pas afficher les caractères codés sur quatre octets comme les émojis.

      La prise en charge des polices peut également réserver certaines surprises. Tous les terminaux ne savent pas afficher des ligatures comme on peut trouver dans Fira Code ou les polices avec les symboles Powerline.

      Et l’on peut également citer la possibilité d’avoir des coins arrondis ou de la transparence parmi les fonctionnalités proposées par des terminaux.

      Terminaux multiples

      Certains logiciels proposent de gérer plusieurs terminaux. Cela peut se faire avec un seul processus qui contrôle plusieurs fenêtres pour gagner en mémoire vive, mais l’approche la plus courante consiste à avoir une seule fenêtre avec plusieurs onglets. Enfin, il existe des terminaux qui reprennent l’approche des gestionnaires de fenêtres par pavage : une seule fenêtre peut être découpée pour afficher plusieurs terminaux et des raccourcis clavier permettent de contrôler le placement des terminaux et passer de l’un à l’autre.

      Performances

      A priori, un terminal ne serait pas l’endroit où l’on accorderait la plus grande importance aux performances. Pourtant, la latence des terminaux n’est pas toujours suffisamment faible pour se faire oublier.

      On peut également citer la vitesse de défilement ou la quantité de mémoire utilisée.

      Simplicité et fonctionnalités

      Certains terminaux se veulent volontairement limités en termes de fonctionnalités. D’autres font plus de choses, et certains vont jusqu’à proposer des greffons ou des API pour permettre des usages avancés.

      Dans les fonctionnalités que l’on retrouve chez certains mais pas chez d’autres, il y a la possibilité de remonter dans l’historique du terminal (le scroll‐back est parfois laissé à un logiciel tiers comme tmux dans certains terminaux), pouvoir cliquer sur les liens, pouvoir lancer des commandes au démarrage du terminal, l’affichage d’images directement dans le terminal, la prise en charge de Wayland, etc.

      Les terminaux

      Les grands classiques

      Tout d’abord, il y a les grands classiques. Le plus connu est xterm, suivi par rxvt et son dérivé rxvt-unicode.

      Ceux intégrés à un environnement de bureau

      Les principaux environnements de bureau ont leur terminal : Konsole pour KDE, GNOME terminal pour GNOME, Xfce terminal pour Xfce et Terminology pour Enlightenment.

      Les terminaux légers

      st est un terminal codé en peu de lignes de C, avec un choix fort de ne pas prendre en charge certaines fonctionnalités et de ne pas faire de gros efforts pour les performances.

      qterminal est un terminal léger s’appuyant sur Qt.

      Les pavants

      GNOME Terminator et Tilix sont deux terminaux qui mettent en avant la possibilité de découper leur fenêtre pour afficher plusieurs shells à l’intérieur.

      Ceux utilisant la bibliothèque VTE

      Il existe plusieurs terminaux s’appuyant sur la bibliothèque VTE (ou des dérivées de cette bibliothèque). Citons termite, sakura et GTKTerm.

      Ceux pour les amoureux de Quake

      Quake avait une console qui s’ouvrait en appuyant sur la touche ² et qui se déroulait depuis le haut de l’écran. Certains terminaux s’en sont inspirés, comme Yakuake, Guake et Tilda.

      Les rapides, en OpenGL

      Alacritty est un terminal récent qui utilise le processeur graphique (via OpenGL). C’est probablement le terminal le plus performant aujourd’hui. En revanche, il ne couvre que peu de fonctionnalités (pas encore d’historique, par exemple).

      kitty est un autre terminal qui tire parti du processeur graphique. Il propose également pas mal de fonctionnalités.

      L’artillerie lourde

      Hyper est un terminal en HTML/CSS/JS (c’est du Electron derrière). Ça ouvre des possibilités intéressantes pour les greffons et l’affichage d’images ou de vidéos, mais ça a également des inconvénients (on peut, par exemple, se poser la question des performances).

      Terminus est un dérivé d’Hyper.

      Upterm, anciennement nommé Black Screen, est également un terminal qui tourne avec Electron. Il fournit également le shell et une auto-complétion graphique des commandes.

      Les originaux

      cool-retro-term est un terminal avec un aspect qui fait penser aux vieux tubes cathodiques. Pour les nostalgiques donc !

      Et le gagnant ?

      Il n’y a pas vraiment de gagnant. Différentes personnes ont différents critères. Pour certains, la prise en charge des ligatures est primordiale, alors qu’elle peut être totalement inutile pour quelqu’un d’autre.

      À titre personnel, j’ai testé pas mal de terminaux et je suis resté sur urxvt. kitty me semble particulièrement intéressant, mais un bogue de ma carte graphique m’empêche de l’utiliser. Alacritty me semble encore un peu trop jeune et limité en fonctionnalités. Je ne suis pas à l’aise avec les versions extrêmes : st est trop limité à mon goût, alors que Hyper est trop lourd. Je n’ai pas particulièrement apprécié les terminaux liés à un environnement de bureau (mais je n’utilise pas d’environnements de bureau) et je suis tombé sur plusieurs bogues gênants pour les terminaux avec la bibliothèque VTE.

      Wikipédia propose une liste de terminaux et une comparaison de certains d’entre eux.

      Et vous, chers lecteurs, qu’utilisez‐vous ? Et pourquoi ?


      N. D. A. : Merci aux nombreuses personnes qui ont commenté pour faire découvrir leur terminal préféré. J’ai ajouté ces terminaux à la dépêche, mais je vous encourage à lire les commentaires, c’est plus détaillé et cela permet de mieux comprendre les spécificités de chaque outil !

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 10.06.2017
      Optimisations et corrections pour Fim 1.2.3

      Fim (File Integrity Manager) sort dans sa version 1.2.3 avec diverses corrections.

      Fim est un gestionnaire de fichiers libre (licence GPL v3) qui permet de gérer de nombreux fichiers de n’importe quelle taille. Il peut, par exemple, gérer des musiques, des photos ou des vidéos. Il est capable de gérer des centaines de milliers de fichiers occupant une taille totale de plusieurs téraoctets. Il peut détecter les fichiers dupliqués et les effacer.

      Fim Logo

      Les nouveautés de la version 1.2.3

      Général

      • passage de Gson à Jackson pour avoir un sérialiseur plus efficace  ;
      • réduction de la quantité de mémoire nécessaire pour charger un State.

      Corrections de bogues

      • correction du problème no 9 : Exception dans le fil d’exécution « principal » java.lang.IllegalStateException ;
      • correction de l’algorithme de comparaison d’état ;
      • lorsque la taille dépasse 1 Go, Fim n’arrondit plus au Go le plus proche ;
      • utilisation du système international d’unités (SI) pour calculer la taille d’un fichier (1 000 — kilo — au lieu de 1 024 — kibi).

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 25.10.2016
      Effacement des doublons et historique complet pour Fim 1.2.2

      Fim (File Integrity Manager) sort dans sa version 1.2.2 avec diverses améliorations et un support de présentation en français.

      Fim est un gestionnaire de fichiers libre (licence GPL v3) qui permet de gérer beaucoup de fichiers de n’importe quelle taille. Il peut, par exemple, gérer des musiques, des photos ou des vidéos. Il est capable de gérer des centaines de milliers de fichiers occupant une taille totale de plusieurs téraoctets. Il peut détecter les fichiers dupliqués et les effacer.

      Fim Logo

      French slides

      Les nouveautés depuis la version 1.2.0

      Général

      • ajout d'un support de présentation en français et en anglais ;
      • effacement des doublons avec la commande rdup ;
      • amélioration de l’affichage de la commande de détection des doublons ;
      • la commande log affiche le détail de toutes les modifications sur les fichiers ;
      • allocation dynamique de files d’exécution pour « hacher » les fichiers en fonction du débit du disque, ce qui permet plus de files d’exécution dans le cas d’un SSD et moins pour un disque dur classique ; ce mode de fonctionnement est activé par défaut ;
      • la commande diff est dépréciée en faveur de la commande status ;
      • l’option -c est dépréciée en faveur de l’option -m ;
      • la commande rdup utilise maintenant l’option -M.

      Corrections de bogues

      • détection correcte en mode « super‐fast » des fichiers qui grossissent ;
      • commentaires avec espaces supportés sous Windows ;
      • diverses corrections, plus de détails dans le journal des modifications.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 21.07.2016
      Sortie de it-edit (Integrated Terminals Editor) 2.91

      IT-Edit (Integrated Terminals Editor) est disponible en version 2.91.

      Cette nouvelle version n'apporte pas de nombreuses améliorations par rapport à la version 2.0, mais constitue une étape importante, car elle est désormais basée sur la nouvelle version majeure de la bibliothèque libvte (bibliothèque implémentant un widget d'émulateur de terminal, utilisé par Gnome-terminal.) IT-Edit se met donc à niveau. À cette occasion, de nombreux bugs et imperfections ont été corrigés.

      capture d'éran de it-edit-2.91

      La plus importante des améliorations étant l'utilisation du chargeur de fichiers intégré à la bibliothèque gtksourceview3.0, qui permet de charger des fichiers codés dans tous les jeux de caractères (pas seulement UTF-8) ; l'éditeur s'est bien sûr amélioré avec le temps et la sortie des nouvelles moutures d'Ubuntu (Xenial) et de Debian (Jessie) ayant bien évolué depuis les versions précédentes.

      Une intégration de la coloration syntaxique pour de nouveaux langages a été faite, comme par exemple le ReST sur lequel se base le générateur de documentation sphinx.

      Concernant cette dernière (sur laquelle le nouveau gnome-terminal est basé) de nouvelles fonctionnalités apparaissent dans les menus contextuels des terminaux de it-edit :

      • ouvrir un nouvel onglet dans le panneau latéral de terminaux ;
      • fermer l'onglet actuel depuis ce panneau latéral ;
      • incrémenter la taille de la police (Font-scale, aussi configurable depuis le panneau de configuration) ;
      • décrémenter la taille de la police (Font-scale, aussi configurable depuis le panneau de configuration) ;
      • réinitialiser le terminal ;
      • et d'autres, accessibles depuis le panneau de configuration ;
      • la mauvaise nouvelle étant que libvte ne permet plus de mettre des images en arrière-plan des terminaux…

      Mais je vous invite à tester ou à mettre à jour vers cette nouvelle version de it-edit en espérant que vous en serez satisfait(e). Je pense qu'il est utile de réellement tester un outil avant de l'adopter.

      PS: it-edit ne se limite pas aux distributions de la famille Debian, il suffit de disposer des bibliothèques nécessaires par le biais du build de it-edit-2.91 basé sur les autotools.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 02.06.2016
      Liquid Prompt 1.10

      Le Liquid Prompt est un prompt fluide affichant de manière limpide des informations utiles dans le prompt de votre shell bash ou zsh. Le liquidprompt était déjà bien rempli de fonctionnalités, certaines ont été ajoutées, d'autres corrigées, et leurs performances ont encore été améliorées avec les 216 commits durant les 17 mois écoulés. Il était temps de sortir une nouvelle version officiellement stable.

      Je profite de cette dépêche pour remercier chaudement les 35 contributeurs qui par leurs patchs ont contribué à cette version.

      Quelques changements sont présentés dans la suite de cette dépêche.

      Pour les détails de cette version les curieux sont invités à consulter l'annonce complète, notamment pour quelques changements incompatibles. En voici un extrait traduit :

      • Les configurations de type LP_ENABLE sont désormais statiques et non plus prises en compte immédiatement après leur modification. Ça se passe via le fichier de configuration et la relance de Liquid Prompt. Ceci a permis de réduire drastiquement le coût d'affichage de chaque prompt.
      • Arrivée de la configuration LP_ENABLE_SUDO permettant une adaptation dynamique lors de l'utilisation de sudo. Noter que pour le moment cette configuration est désactivée, par défaut de capacité de différenciation immédiate entre une autorisation et un refus.
      • Beaucoup de corrections de bugs pour les indicateurs d'heure analogique, de température machine, de charge CPU et de batterie.
      • Meilleure prise en compte de l'usage de tmux par l'amélioration de sa détection.
      • Pour Zsh, l'option nopromptsubstest maintenant activée par défaut. Cela peut impacter notamment des définitions de RPS1 (défini en dehors de Liquid Prompt).

      Note : deux bugs sur OS X ont déjà été remontés depuis la release, donc il est recommandé d'utiliser la branche master pour ce système d'exploitation.

      Copie d'écran de Liquid Prompt

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 25.05.2016
      Focus sur les performances avec Fim 1.2.0

      Fim (File Integrity Manager) sort dans sa version 1.2.0 avec divers gains de performance.

      Fim est un gestionnaire de fichiers libre (licence GPLv3) qui permet de gérer beaucoup de fichiers de n'importe quelle taille. Il peut par exemple, gérer des photos ou des vidéos. Il est capable de gérer des centaines de milliers de fichiers occupant une taille totale de plusieurs téraoctets. Il peut détecter les fichiers dupliqués et aider à les effacer.

      Fim Logo

      Les nouveautés de la version 1.2.0

      Amélioration globale de la performance

      • Diminution de la taille du state en mémoire et sur le disque en utilisant Ascii85 au lieu de Hexa pour stocker les hash
      • Ajout du Super-fast commit
      • Augmentation de la capacité à gérer une très grande quantité de fichiers (1 098 138 fichiers fonctionne pour moi)
      • Optimisation de la comparaison des state pour pouvoir comparer rapidement deux State contenant 1 000 000 de fichiers

      Général

      • Fim est maintenant distribué sous forme d'image Docker sur Docker Hub
      • Chaque commit sur Fim est maintenant testé sur Mac OS X grâce au builder Travis Mac

      À noter : le format utilisé pour le state est nouveau et non-compatible avec le format précédent. Cela nécessite donc une ré-indexation / une nouvelle table de hashs : fim ci -y -c "Migration vers Fim 1.2.0".

      Corrections de bogues

      • Vérification des droits sur le répertoire .fim avant toute exécution de commandes
      • Ignore maintenant les millisecondes des dates de modification (certains JDK ne les écrivent pas ou les écrivent à 0)
      • Ajout de l'option --output-max-lines permettant d'allonger la liste présentée maintenant par défaut : 200 lignes du même type tronquées.
      • Les fichiers vides ne sont plus répertoriés comme dupliqués.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 13.11.2015
      WebVim, une distribution Vim pour le dévelopment web

      WebVim est une distribution Vim qui vient avec un lot de greffons pré-configurés et optimisés pour le développement web et JavaScript/node.js.

      Logo WebVim

      WebVim offre par défaut quelques fonctionnalités sympas, dignes de certains IDE et éditeurs de code spécialisés :

      • coloration syntaxique ;
      • affichage des erreurs de syntaxes et de styles ;
      • auto-complétion ;
      • refactoring ;
      • curseurs multiples ;
      • formatage et alignement automatiques ;
      • prise en compte de conventions d'édition (editorconfig) ;
      • prise en charge de git ;
      • navigation dans les modules nodes.js ;
      • un mode hardcore (où par exemple la touche Esc et les flèches sont désactivées) ;
      • et tout ce que Vim fournit par défaut (par exemple la vérification orthographiques) !

      WebVim utilise le gestionnaire de greffons vim-plug en arrière plan et un système de chargement et de configuration avancé.

      Historique

      J'ai toujours été fasciné par certains de mes collègues et leur dextérité à éditer des fichiers textes plus vite que n'importe qui, mais j'ai utilisé pendant des années des outils tels qu'Eclipse ou Netbeans pour le développement et Vim pour l'édition de fichiers de configuration ou des modifications rapides en mode console.

      Au fur et à mesure du temps, alors que mes doigts apprennent tous seuls les raccourcis Vim, je me dis qu'il est possible de migrer complètement vers cet éditeur pour mes tâches de développement. En fonction des besoins j'ai commencé à modifier mon .vimrc ajouter un greffon puis un autre. Comme beaucoup j'ai créé un dépôt de type dotfiles pour partager ma configuration. De fil en aiguille, mon répertoire .vim partagé est devenu WebVim.

      Aujourd'hui c'est l'éditeur que j'utilise au jour le jour pour tous mes développements.

      Philosophie

      Le but est de prendre en charge mes cas d'utilisation bien précis, notamment l'édition de ces types de fichiers au sein de projets web :

      • HTML ;
      • CSS, SCSS ;
      • JavaScript côté client et serveur ;
      • JSON ;
      • markdown.

      Édition d'un module JavaScript

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 11.11.2015
      Kakoune, un éditeur de texte qui a du caractère

      Kakoune est un éditeur de texte en console qui gagne a être connu. Cette dépêche a pour but de le faire découvrir à plus de monde.

      NdM : Le logiciel est placé par ses auteurs dans le domaine public.

      Présentation

      Logo de Kakoune Kakoune avait été évoqué dans le journal Tour d'horizon des éditeurs de texte pour le terminal il y a bientôt 1 an.

      Il a depuis continué d'évoluer assez rapidement et s'est doté récemment d'un site web Kakoune.org.

      Kakoune, c'est plus de 3 ans de développement et plus de 14000 lignes de code c++11 ; il cumule aujourd'hui plus de 30 contributeurs.
      De toute la famille des éditeurs inspiré de vi/vim, c'est le seul qui va au delà du clone et repense l'interaction avec le texte.

      Kakoune reprend les grand concepts de la famille vi, à savoir :

      • un éditeur avec plusieurs modes (édition, sélection, commande, …) ;
      • les séquences de touches forment un langage d'édition de texte.

      Fonctionnalités — Spécificités

      Kakoune se définit lui-même comme :

      • inspiré par Vim (c’est un éditeur modal) ;
      • plus rapide (dans le sens "moins de touches à presser") ;
      • permettant la sélection multiple ;
      • ayant un design orthogonal.

      Fonctionnalités

      • sélection multiple comme principale façon d'interagir ;
      • puissantes fonctions de manipulation des sélections :
        • sélection de toutes les correspondances d'une expression rationnelle dans les sélections en cours,
        • conservation de toutes les sélections contenant ou ne contenant pas de correspondances à une expression rationnelle,
        • divisions des sélections en cours avec une expression rationnelle,
        • objets texte (paragraphe, phrase, blocs imbricables) ;
      • puissantes primitives de manipulation du texte :
        • alignement des sélections,
        • rotation du contenu des sélections,
        • manipulation de la casse,
        • indentation,
        • envoi de chaque sélection à un filtre extérieur ;
      • architecture client-serveur :
        • clients multiples sur la même session d'édition,
        • utilise tmux ou votre window manager pour gérer les fenêtres ;
      • interaction facile avec les programmes externes ;
      • aide contextuelle automatique ;
      • complétion automatique lors de la frappe ;
      • macros ;
      • crochets ;
      • coloration syntaxique :
        • prise en charge de plusieurs langages dans le même tampon,
        • coloration différente d'un même tampon dans des fenêtres différentes.

      Quelques exemples

      Afin d'illustrer la manière de travailler avec Kakoune, voici quelques exemples expliqués.

      Le premier exemple permet d'aligner les signes = apparaissant sur trois lignes consécutives.

      3Xs=<RET>&
      
      • 3X sélectionner 3 lignes à partir de la ligne courante
      • s entrée en mode sélection
      • =<RET> on sélectionne le = dans chaque ligne
      • & aligner les sélections

      Le second exemple montre comment remplacer un motif par un autre dans le tampon courant (communément appelé "remplacement global").

      %sfoo<RET>cbar<ESC>
      
      • % sélectionner l'intégralité du tampon
      • sfoo<RET> sélectionner les instances de l'expression régulière "foo" dans la sélection courante
      • c entrer en mode d'insertion pour remplacer le contenu des sélections
      • bar<ESC> insérer "bar" puis quitter le mode d'insertion

      Pour les vimistes, un document, Migrating from VIm, explique les différences de concepts.

      La principale différence étant que dans Kakoune, on sélectionne d'abord le texte à manipuler, puis on lance des actions sur la ou les sélections. Comme tout tourne autour des sélections, le choix a été fait que les commandes avec Shift étendent celles-ci. Par exemple : w sélectionne un mot et Shift-w ajoute le mot suivant à la sélection.

      Ce choix a nécessité dans certain cas de rompre la compatibilité avec vim, par exemple J sélectionne vers le bas et c'est Alt-J pour joindre deux lignes.

      Compilation — Installation

      Kakoune fonctionne sous les Unix, ses dépendances sont :

      • libboost-all-dev
      • libncursesw5-dev

      Développé en C++11, il nécessite un compilateur compatible, soit GCC >= 4.8 ou clang = 3.4

      Pour les personnes intéressées qui voudraient tester Kakoune, les instructions de compilation sont simples et tiennent en quelques lignes :

      git clone https://github.com/mawww/kakoune.git
      cd kakoune/src
      make
      ./kak

      Il existe aussi beaucoup de recettes (OSX, Arch, Fedora, etc.) dans la documentation principale, section installation

      Avenir

      Bien que Kakoune continue d'évoluer, il est tout à fait utilisable en tant qu'éditeur principal. Des modifications incompatibles avec l'existant peuvent encore arriver de temps à autres mais se font de plus en plus rares. La prise en charge de l'édition de code C ou C++ est bien en place, et le modèle d’extensibilité semble fonctionnel.

      Les prochains points clé pour Kakoune sont désormais :

      • davantage d'utilisateurs afin de développer la prise en charge de plus de langages ;
      • de cas d'utilisations (voir Advertise Kakoune).

      Pas de version 1.0 à l'horizon, pas du tout de numéro de version en fait. L'auteur préfère avoir une branche master stable grâce à de nombreux tests (171 à ce jour) et une intégration continue (voir Begin versioning/releasing kakoune?).

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 02.11.2015
      Fim 1.1.0

      Fim (File Integrity Manager) est un gestionnaire de fichiers libre (licence GPLv3) qui permet de gérer beaucoup de fichiers de n'importe quelle taille. Il peut par exemple, gérer des photos ou des vidéos. Il est capable de gérer des centaines de milliers de fichiers occupant une taille totale de plusieurs téraoctets. Il peut détecter les fichiers dupliqués et aider à les effacer.

      Logo de Fim

      Les nouveautés de la version 1.1.0 :

      • réécriture de l'algorithme de hachage pour hacher un bloc au début, un au milieu et un à la fin (détails ici) ;
      • détection de corruption due au matériel ou de bug du système de fichiers (détails ici) ;
      • sauvegarde et restauration des permissions des fichiers, utilisation des labels SELinux si disponibles (détails ici) ;
      • prise en compte des fichiers .fimignore pour ignorer des fichiers ou des répertoires (détails ici).

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 28.10.2015
      Atelier CLI de la semaine 45/2015 à Bordeaux

      Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème.

      Au cours de l'atelier CLIdu mardi 03 novembre, j'ouvrirais le premier atelier consacré aux contrôles d'accès dont le sujet sera les permissions Unix traditionnelles, abrèv. TUP. Lieu : Le Node 12 rue des Faussets 33000 Bordeaux.

      L'atelier CLI suivant, fixé au mardi 10 novembre, sera ouvert à la pratique à l'aide d'exemples concrets. Lieu : Labx, à la Cité numérique, 2 rue Marc Sangnier 33130 Bègles.

      Les ateliers CLI ont lieu :

      • débutant : animé par Stéphane Ortega, le lundi de 19h00 à 20h30;
      • avancé : animé par un professionnel ou un expert, le mardi de 20h00 à 22h00.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 26.10.2015
      Katal, catalogue de fichiers

      Katal est un projet GPLv3/Python3/CLI/Linux-Windows : il permet de créer un catalogue de fichiers à partir de différentes sources, en filtrant les fichiers à récupérer, en les renommant à la volée; on peut alors étiqueter les fichiers obtenus.

      Le répertoire de destination contient les fichiers du catalogue, une base de données, un dossier .trash et un dossier pour les logs. J'ai l'habitude de placer dans le répertoire de destination le script katal.py; ainsi, je déplace le catalogue en même temps que l'outil qui me permet de le gérer.

      De l'aide est disponible dans le fichier README.md : voyez ici.
      Voyez aussi le résultat de $ katal -h .

      Sommaire

      L'histoire

      Un copain m'avait demandé de l'aider à classer des dizaines de milliers de photos tirées de milliers de répertoires différents, mélangées avec toutes sortes de fichiers (textes, vidéos); beaucoup de photos identiques portaient des noms différents.

      Je voulais obtenir un catalogue des fichiers :

      1. qui avaient l'extension de fichiers image (.jpg, .tiff, …) ;
      2. qui avaient une taille supérieure à 2 Mo pour éliminer les vignettes ;
      3. sans doublon (=aucun fichier ayant le même contenu qu'un autre) ;
      4. avec la possibilité d'étiqueter (=avec des tags) les images ;
      5. avec la possibilité de renommer les fichiers ;
      6. avec des fichiers de logs verbeux pour garder la trace de mes essais et de mes erreurs ;
      7. le tout sur Linux/Mac/Windows puisque je passais d'un ordinateur à l'autre.

      Installation

      $ pip install katal

      katal est en effet hébergé sur Pypi.

      mais aussi :

      $ wget https://raw.githubusercontent.com/suizokukan/katal/master/katal/katal.py

      … puisque le projet Katal tient en un seul fichier, katal.py, qui peut être placé dans le répertoire de destination.

      Utilisation

      Créer le répertoire de destination, qui contiendra les fichiers du catalogue :

      $ katal --new=destdir

      … et accepter de télécharger le fichier de configuration par défaut qui sera placé dans le répertoire de destination (dans un sous répertoire nommé .katal)

      Placez-vous ensuite à l'intérieur du répertoire de destination.

      $ cd destdir

      Vous pouvez voir ce que pense Katal de ce répertoire en tapant :

      $ katal --infos

      À l'intérieur du répertoire de destination, modifier le fichier de configuration ./katal/katal.ini :

      Changer la source, par exemple :

      [source]
      path : ~/masource/photos/

      Katal recherchera de manière récursive dans ce répertoire.

      Changer le nom des fichiers qui seront copiés dans le répertoire de destination, par exemple :

      [target]
      name of the target files : INTTIMESTAMP_SIZE__DATABASE_INDEX.SOURCE_EXTENSION2

      … pour avoir des fichiers du type 1445584562_123__1.jpg (=timestamp du fichier source, taille du fichier source, index dans la base de données du répertoire de destination)

      Changer la fonction d'évaluation permettant de faire le tri entre les fichiers de la source, par exemple :

      … si vous voulez les fichiers python du répertoire source :
      [source]
      eval : sieve1
      [source.sieve1]
      name : .*\.py$
      … si vous voulez les fichiers python du répertoire source faisant plus d'un mégaoctet :
      [source]
      eval : sieve1
      [source.sieve1]
      name : .*\.py$
      size : >1000000
      … si vous voulez les fichiers python du répertoire source faisant plus d'un mégaoctet OU les .jpg :
      [source]
      eval : sieve1 or sieve2
      [source.sieve1]
      name : .*\.py$
      size : >1000000
      [source.sieve2]
      name : .*\.jpg$

      Tester le fichier de configuration ./katal/katal.ini :

      $ katal --select

      Katal vous montre alors ce qui se passerait si vous acceptiez la copie de la source vers la destination. Par exemple :

        +  selected /home/suizokukan/projets/dysodos/dysodos.py (file selected #1)
        -  discarded "/home/suizokukan/projets/dysodos/.git/description" : incompatibility with the sieves
        -  discarded "/home/suizokukan/projets/dysodos/.git/info/exclude" : incompatibility with the sieves
      
      [...]
      
        o  everything ok : no anomaly detected. See details above.
        o size of the selected file(s) : 3877 bytes
        o number of selected files (after discarding 36 file(s)) : 1, 2.70% of the source files.
        o required space : 3877 bytes; available space on disk : ~35.62 Go (35619852288 bytes) (ok)
        o e.g. … "/home/suizokukan/projets/dysodos/dysodos.py" would be copied as "/home/suizokukan/projets/katal/target2/5474c904__0.py" .
        Do you want to add the selected files to the target dictionary (".") ? (y/N) 
      

      Si vous êtes d'accord, répondez oui en tapant 'y' + entrée :

          … (1/1) copying "/home/suizokukan/projets/dysodos/dysodos.py" to "/home/suizokukan/projets/katal/target2/5474c904__0.py" .
          = all files have been copied, let's update the database… =
          = … database updated =
      

      Katal affiche automatiquement le contenu du catalogue (ici, un seul fichier) :

         = informations about the "." (path: "/home/suizokukan/projets/katal/target2") target directory =
      +--------------------+--------------------+------+--------------------+------------------+
      | hashid/base64      | name               | tags | source name        | source date      |
      +--------------------+--------------------+------+--------------------+------------------+
      | […]f8SfE3Tzc+UP0s= | […]/5474c904__0.py |      | […]odos/dysodos.py | 2014-11-25 19:23 |
      +--------------------+--------------------+------+--------------------+------------------+
      

      Vous pouvez à tout moment afficher ces informations sur le catalogue à l'aide de l'option -ti :

      $ katal -ti

      (ti : target informations)

      =======================================================
      === Katal v.0.1.3 (launched at 2015-10-25 17:19:06) ===
      =======================================================
        = target directory given as parameter : "." (path : "/home/suizokukan/projets/katal/target2")
        = no config file specified on the command line : let's search a config file in the current directory…
        * config file name : "/home/suizokukan/projets/katal/target2/.katal/katal.ini" (path : "/home/suizokukan/projets/katal/target2/.katal/katal.ini")
          … config file found and read (ok)
        = source directory : "~/projets/dysodos" (path : "/home/suizokukan/projets/dysodos")
        = informations about the "." (path: "/home/suizokukan/projets/katal/target2") target directory =
      +--------------------+--------------------+------+--------------------+------------------+
      | hashid/base64      | name               | tags | source name        | source date      |
      +--------------------+--------------------+------+--------------------+------------------+
      | […]f8SfE3Tzc+UP0s= | […]/5474c904__0.py |      | […]odos/dysodos.py | 2014-11-25 19:23 |
      +--------------------+--------------------+------+--------------------+------------------+
      === exit (stopped at 2015-10-25 17:19; total duration time : 0:00:00.004414) ===
      

      Vous pouvez enfin étiqueter un ou plusieurs fichiers :

      Si vous voulez ajouter le tag "mytag" aux fichiers Python :

      $ katal --addtag=mytag --to=*.py

      Si vous voulez ajouter le tag "mytag" à un seul fichier :

      $ katal --addtag=mytag --to=5474c904__0.py

      Vous pouvez aussi :

      • supprimer toutes les étiquettes d'un ou plusieurs fichiers (--rmnotags) ;
      • supprimer un fichier ou plusieurs fichiers du catalogue (--targetkill) ;
      • supprimer les fichiers qui n'ont pas de tags (--rmnotags) ;
      • supprimer de la base de données les fichiers qui n'existent pas dans le répertoire de destination (--cleandbrm).

      Et d'autres choses encore, accessibles dans le fichier README.md ou en consultant le résultat de $ katal -h .

      Et la suite ?

      J'ai essayé d'écrire du code lisible par tous : pylint à 10, documentation abondante, commentaires et documentation en anglais…
      Je serais ravi de vos commentaires et de vos suggestions d'amélioration !

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 08.10.2015
      Atelier CLI de la semaine 41/2015 à Bordeaux

      Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème.

      L'atelier CLI du 13/10/2015 sera consacrée au langage Python, Alexandre Devert en présentera une introduction.

      L'atelier suivant, fixé au mardi 20 octobre, sera ouvert à la pratique à l'aide d'exemples concrets.

      Alexandre Devert est chercheur, ou plutôt « fouilleur de données » comme il aime à se décrire. Il écrit de nombreux scripts dans le langage Python afin d'explorer des résultats d'expériences.

      Il est l'auteur du livre « matplotlib Plotting Cookbook », aux éditions Packt Publishing. matplotlib est une bibliothèque graphique 2D implémentée en Python.

      Les ateliers CLI ont lieu :

      • pour le niveau débutant : animé par Stéphane Ortega, le lundi de 19h00 à 20h30 ;
      • pour le niveau avancé : animé par un professionnel ou un expert, le mardi de 20h00 à 22h00.

      Ils se dérouleront dans les locaux du Labx, à la Cité numérique, 2 rue Marc Sangnier 33130 Bègles.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 08.09.2015
      Sortie de Fim 1.0.2, qui vérifie l'intégrité de vos fichiers

      Fim (File Integrity Manager) est un gestionnaire de fichiers libre (licence GPLv3) qui permet de gérer beaucoup de fichiers de n'importe quelle taille. Il peut par exemple, gérer des photos ou des vidéos. Il est capable de gérer des centaines de milliers de fichiers occupant une taille totale de plusieurs téraoctets. Il peut détecter les fichiers dupliqués et aider à les effacer.

      Fim

      Fim est un outil ligne de commande qui permet de gérer les fichiers avec un esprit qui ressemble à Git.
      Il est différent de Git car il ne conserve pas le contenu des différentes versions des fichiers.
      Vous ne pouvez pas utiliser Fim pour retrouver un contenu que vous auriez perdu.

      Fim conserve dans le répertoire .fim un état de chaque fichier dans des index qui contiennent :

      • Le nom, la taille et la date de modification du fichier
      • 3 hash du contenu (hash du contenu complet, hash du deuxième bloc de 1 MB, hash du deuxième bloc de 4 KB)

      Les deux hash supplémentaires qui sont calculés sont utilisés lors des comparaisons rapides.

      Voici les commandes disponibles dans Fim:

      • init : initialise le répertoire .fim et crée le premier index contenant l'état des fichiers,
      • ci ou commit : crée un nouvel index contenant l'état actuel des fichiers,
      • diff : permet de savoir quel fichier a été ajouté, modifié, effacé, déplacé, renommé, dupliqué. On peut avoir un résultat rapide en utilisant les options -m ou -k ou -f ,
      • log : affiche l'historique des différents index et un résumé des modifications qui ont été apportées,
      • fdup ou find-duplicates : affiche la liste des fichiers dupliqués.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 08.09.2015
      Atelier CLI de la semaine 37/2015 à Bordeaux

      Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème.

      Pour cette rentrée, au cours de l'atelier CLI du 15/09/2015, Jean-Maxime Philippeaux présentera le générateur de site Web statique Hugo.

      Les ateliers CLI ont lieu :

      • chaque mardi de 20h00 à 22h00 pour les utilisateurs avancés;
      • un mercredi sur deux de 19h00 à 20h30 pour les utilisateurs débutants.

      à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 28.04.2015
      Atelier CLI de la semaine 22/2015 à Bordeaux

      Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème.

      Au cours de l'atelier du 28/04/2015, on pourra découvrir ou redécouvrir
      rsync, une commande dédiée à la synchronisation à distance, autrement dit la sauvegarde de données.

      Les ateliers CLI ont lieu :

      • chaque mardi de 20h00 à 22h00 pour les utilisateurs avancés,
      • un mercredi sur deux de 19h00 à 21h00 pour les utilisateurs débutants,

      dans les locaux du Labx, à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 21.04.2015
      Un point d'avancement sur Neovim

      Le logo de Neovim

      Neovim est un éditeur de texte, issu d'un fork de Vim. Il vise à le rendre plus moderne. En particulier, faciliter le développement et l'utilisation de greffons, et permettre de l'intégrer plus facilement dans d'autres outils.

      Le fork date d'un peu plus d'un an et le travail commence à payer. En plus d'un gros nettoyage de la base de code, les développeurs de Neovim ont mis en place un système de plugins, de greffons, qui peuvent désormais tourner à l'extérieur du processus principal et communiquer avec lui via msgpack. On peut également apprécier la possibilité de lancer un terminal à l'intérieur de Neovim, grâce à l'inclusion récente de la libvterm.

      Mais pour accélérer le développement, Neovim a besoin de vous. Le développeur principal, @tarruda passe une partie de son temps sur Neovim et une autre partie à faire des missions en freelance pour gagner sa vie. Grâce à des dons, il pourrait diminuer le temps passé sur les missions, et ainsi passer plus de temps à faire vivre Neovim.

      Personnellement, je suis un utilisateur comblé de Neovim depuis quelques mois. Bien que celui-ci soit toujours en version alpha, il est très stable et le passage de Vim à Neovim s'est fait sans aucun souci. Aussi, j'ai participé à l'appel à dons et vous encourage à faire de même pour promouvoir ce projet qui le mérite bien !

      Commentaires : voir le flux atom ouvrir dans le navigateur

       


       

      Publié le 25.04.2016
      Atelier CLI : TDD en Bash, mardi 14 avril 2015 ⌚ 20h ⌘ Bordeaux

      Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème.

      Au cours de l'atelier du mardi 14 avril 2015, vous pourrez découvrir shebang_unit, un framework de test automatisés pour Bash 4 basé sur xUnit, développé et présenté par Michael Borde.

      L'atelier se tiendra dans les locaux du Labx, à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

      Les ateliers CLI ont lieu dans les locaux du Labx, à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

      • chaque mardi de 20h00 à 22h00 pour les utilisateurs avancés,
      • un mercredi sur deux de 19h00 à 21h00 pour les utilisateurs débutants,

        Commentaires : voir le flux atom ouvrir dans le navigateur

         


         

        Publié le 25.04.2016
        Atelier CLI le 31 mars 2015 à Bordeaux

        Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème. Au cours de l'atelier du 31 mars 2015, vous pourrez découvrir ou redécouvrir Mutt, un client mail orienté terminal : présentation, configuration et utilisation.

        L'atelier se tiendra dans les locaux du Labx, à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

        Les ateliers CLI ont lieu dans les locaux du Labx, à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

        • chaque mardi de 20h00 à 22h00 pour les utilisateurs avancés,
        • un mercredi sur deux de 19h00 à 21h00 pour les utilisateurs débutants,

        Commentaires : voir le flux atom ouvrir dans le navigateur

         


         

        Publié le 13.03.2015
        Programme des ateliers CLI pour la semaine 12 à Bordeaux

        Les ateliers CLI (Command Line Interface) permettent de progresser en ligne de commande au sein d'un groupe, autour d'un outil ou d'un thème.

        Le mardi 17 mars, l'atelier avancé portera sur la syntaxe Markdown et la publication d'articles avec le moteur de pages Web statiques Hugo.

        Les ateliers CLI ont lieu :

        • chaque mardi de 20h00 à 22h00 pour les utilisateurs avancés;
        • un mercredi sur deux de 19h00 à 21h00 pour les utilisateurs débutants;

        dans les locaux du Labx, à la Fabrique Pola, rue Marc Sangnier 33130 Bègles.

        Commentaires : voir le flux atom ouvrir dans le navigateur