Récupérer la partie numérique de la version du kernel

Résolu
lenainjaune Messages postés 726 Date d'inscription   Statut Contributeur Dernière intervention   -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour à tous :) !

J'ai cherché sans succès une solution à mon problème.

Je souhaite récupérer le numéro de version de mon kernel et uniquement le numéro. Le but étant d'automatiser un traitement pour récupérer la liste des anciens kernels (donc sans celui actuel).

La doc linux indique
uname -r
. Chez moi ça donne : 3.13.0-98-generic

Donc je voudrais éliminer :
linux-headers-3.13.0-98
linux-headers-3.13.0-98-generic
linux-image-3.13.0-98-generic

Pour cela je dois juste récupérer : 3.13.0-98

Est-ce que
uname -r
retourne toujours xxx-generic ? Auquel cas avec un bête
sed
le tour est joué...

Sinon, comment obtenir de manière sûre la partie numérique seulement ?

Pour info, la commande que j'utilise pour lister est :
dpkg --list | grep 'linux-headers\|linux-image' | grep -v "linux-image-generic\|`uname -r`"


Si quelqu'un peut m'aider.
Cordialement,
lnj
J'ai des questions à toutes vos réponses. (Woody Allen)

3 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    D'après
    man uname
    ce qui correspond le plus à ce que tu cherches est
    uname -r
    mais peut effectivement comporter l'architecture ou le suffixe générique. Généralement c'est ce que tu veux :

     ls -l /usr/src/linux-headers-$(uname -r)


    Dans ton cas, un sed ou une opération sur les chaînes semble le plus simple :
    https://stackoverflow.com/questions/4563060/how-to-cut-the-last-field-from-a-shell-string

    (mando@aldur) (~) $ s=$(uname -r)
    (mando@aldur) (~) $ echo $s
    4.5.0-2-amd64
    (mando@aldur) (~) $ echo ${s%-*}
    4.5.0-2


    Après le mieux c'est de récupérer le morceaux avec une expression régulière. Ensuite
    sed
    ,
    grep
    ou
    egrep
    sont autant de solutions possibles.

    echo $(uname -r) | egrep -o "(([0-9\.]+-)*[0-9\.]+)"


    Bonne chance
    1
    1. lenainjaune Messages postés 726 Date d'inscription   Statut Contributeur Dernière intervention   62
       
      Merci :)

      Bien le
      grep -o
      pour n'afficher que ce qui correspond, par contre
      echo ${s%-*}
      je dois avouer que ça me semble plus obscure (même si c'est plus portable apparemment).

      Donc au final, ça me donne :
      dpkg --list | grep 'linux-headers\|linux-image' | grep -v "linux-image-generic\|`uname -r | egrep -o '(([0-9\.]+-)*[0-9\.]+)'`"


      Et ça marche nickel.

      Et sinon, on ne peut pas le récupérer ailleurs ce numéro, plutôt que de le déduire ?
      0
  2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    En terme de portabilité la syntaxe
    echo
    se discute, car elle pré-suppose que tu fais du bash. La technique avec
    egrep
    est relativement portable et peut être adaptée avec
    grep
    en mettant des \ aux bons endroits.

    Concernant la syntaxe :
    -
    echo ${s%-*}
    vient à la base de
    echo $s
    ou
    echo ${s}
    qui signifie "afficher le contenu de la variable
    s
    " ;
    %
    désigne la chaîne à extraire,
    -
    est le séparateur sur lequel on coupe, et
    *
    désigne le reste.
    - concernant
    egrep
    , la syntaxe est logique à condition de savoir utiliser des expressions rationnelles (ou régulières), détaillées dans
    man grep
    ou sur wikipedia.

    Enfin, concernant l'idée de trouver le numéro de version ailleurs c'est une bonne idée. Je suspecte qu'il est extrait de
    cat /proc/version
    . Mais si tu lances cette commande (qui en gros, consiste à interroger le noyau au travers du système de fichiers virtuel
    /proc
    ) tu verras que tu feras face aux mêmes difficultés pour extraire précisément le numéro de version. La solution avec
    uname -r
    reste donc plus simple à réaliser.

    Bonne chance
    0
    1. lenainjaune Messages postés 726 Date d'inscription   Statut Contributeur Dernière intervention   62
       
      Merci pour ces explications très claires.

      Le bash un jour, il faudra que je maîtrise un peu mieux ; ça ne m'empêche pas d'écrire des scripts mais bon je googlelise à chaque commande ou presque :D

      Le
      grep
      en revanche je le comprends pas trop mal. Et au fait, dans ton motif tu indiques ' * ' après la première partie, cela supposerait-il qu'une version de Linux pourrait être : 1.2-3.4-5 (donc avec plusieurs tirets) ? Jamais vu...

      J'avais déjà testé
      cat /proc/version
      et c'est pour ça que je suis venu demander de l'aide ;)
      0
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Le bash un jour, il faudra que je maîtrise un peu mieux ; ça ne m'empêche pas d'écrire des scripts mais bon je googlelise à chaque commande ou presque :D

    Disons que bash c'est bien quand tu es pressé ou que tu veux faire des trucs très simples. C'est surtout très bien quand ça implique des commandes linux (genre
    uname
    ) car ça t'évite les
    popen
    que tu aurais à faire dans un autre langage.

    Mais garde à l'esprit que dès que tu fais des choses plus compliquées, un langage plus propre, plus portable et plus évolué est souvent préférable. Par exemple python est un choix qui tient tout à fait la route pour manipuler des fichiers et traiter du texte.

    Le grep en revanche je le comprends pas trop mal. Et au fait, dans ton motif tu indiques ' * ' après la première partie, cela supposerait-il qu'une version de Linux pourrait être : 1.2-3.4-5 (donc avec plusieurs tirets) ? Jamais vu...

    Oui tout à fait, ce motif serait accepté. En fait une bonne manière de faire pour tester une expression rationnelle, c'est de faire un
    echo
    et tu regardes si
    grep
    laisse passer ou non la chaîne.

    (mando@velvet) (~) $ echo 1.2-3.4-5 | egrep -o "(([0-9\.]+-)*[0-9\.]+)"
    1.2-3.4-5


    L'option
    --color
    est aussi très pratique pour construire progressivement ton expression régulière et vérifier que tu rattrapes bien ce que tu veux.

    Exemple

    echo 1.2-3.4-5 | egrep --color "(([0-9\.]+-)?[0-9\.]+)"


    Concernant l'existance d'un tel format de numéro de version je n'en ai pas vu non plus, ce qui signifie que tu peux très bien te limiter à :

    uname -r | egrep -o "(([0-9\.]+-)?[0-9\.]+)"


    ... puisque le
    ?
    signifie entre 0 et 1 répétition. Maintenant mettre une
    *
    , même si c'est discutable, ce n'est pas faux en soit, et ça permet de gérer le cas où justement tu aurais une expression de la forme
    1.2-3.4-5
    .

    Note que tu pourrais aussi limiter le résultat à la première (et normalement la seule) sous-chaîne qui matche. Là ce serait vraiment pour être ceinture et bretelle. Mais si on reprend ton exemple :

    (mando@velvet) (~) $ echo 1.2-3.4-5 | egrep -o "(([0-9\.]+-)?[0-9\.]+)"
    1.2-3.4
    5


    ... on voit qu'ici la solution avec
    ?
    régirait sur deux sous chaînes. Pour garantir que ce genre de situation ne peut pas arriver, on peut par exemple écrire :

    echo 1.2-3.4-5 | egrep -o "(([0-9\.]+-)?[0-9\.]+)" | head -n 1


    J'avais déjà testé cat /proc/version et c'est pour ça que je suis venu demander de l'aide ;)

    Tu as bien fait, en tout cas ta démarche était tout à fait logique :-)

    Bonne chance
    0
    1. lenainjaune Messages postés 726 Date d'inscription   Statut Contributeur Dernière intervention   62
       
      Merci beaucoup pour toutes les explications très claires et aussi pour tes trucs et astuces.

      Au plaisir mamiemando :)
      0
    2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      De rien, bonne continuation :-)
      0