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

Résolu/Fermé
lenainjaune Messages postés 672 Date d'inscription mercredi 7 mai 2008 Statut Contributeur Dernière intervention 23 août 2024 - Modifié par lenainjaune le 15/10/2016 à 20:01
mamiemando Messages postés 33302 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 3 octobre 2024 - 21 oct. 2016 à 08:04
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)
A voir également:

3 réponses

mamiemando Messages postés 33302 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 3 octobre 2024 7 793
Modifié par mamiemando le 15/10/2016 à 21:43
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
lenainjaune Messages postés 672 Date d'inscription mercredi 7 mai 2008 Statut Contributeur Dernière intervention 23 août 2024 52
15 oct. 2016 à 22:35
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
mamiemando Messages postés 33302 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 3 octobre 2024 7 793
17 oct. 2016 à 13:40
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
lenainjaune Messages postés 672 Date d'inscription mercredi 7 mai 2008 Statut Contributeur Dernière intervention 23 août 2024 52
17 oct. 2016 à 19:18
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
mamiemando Messages postés 33302 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 3 octobre 2024 7 793
19 oct. 2016 à 08:02
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
lenainjaune Messages postés 672 Date d'inscription mercredi 7 mai 2008 Statut Contributeur Dernière intervention 23 août 2024 52
20 oct. 2016 à 22:53
Merci beaucoup pour toutes les explications très claires et aussi pour tes trucs et astuces.

Au plaisir mamiemando :)
0
mamiemando Messages postés 33302 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 3 octobre 2024 7 793
21 oct. 2016 à 08:04
De rien, bonne continuation :-)
0