Signaler

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

Posez votre question lenainjaune 370Messages postés mercredi 7 mai 2008Date d'inscription ContributeurStatut 7 décembre 2016 Dernière intervention - Dernière réponse le 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
Afficher la suite 
Utile
+1
moins plus
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 :
http://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
lenainjaune 370Messages postés mercredi 7 mai 2008Date d'inscription ContributeurStatut 7 décembre 2016 Dernière intervention - 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 ?
Répondre
Ajouter un commentaire
Utile
+0
moins plus
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
lenainjaune 370Messages postés mercredi 7 mai 2008Date d'inscription ContributeurStatut 7 décembre 2016 Dernière intervention - 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 ;)
Répondre
Ajouter un commentaire
Utile
+0
moins plus
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
lenainjaune 370Messages postés mercredi 7 mai 2008Date d'inscription ContributeurStatut 7 décembre 2016 Dernière intervention - 20 oct. 2016 à 22:53
Merci beaucoup pour toutes les explications très claires et aussi pour tes trucs et astuces.

Au plaisir mamiemando :)
Répondre
mamiemando 27320Messages postés jeudi 12 mai 2005Date d'inscription ModérateurStatut 8 décembre 2016 Dernière intervention - 21 oct. 2016 à 08:04
De rien, bonne continuation :-)
Répondre
Ajouter un commentaire

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !