Récupérer la partie numérique de la version du kernel
Résolu
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
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
Sinon, comment obtenir de manière sûre la partie numérique seulement ?
Pour info, la commande que j'utilise pour lister est :
Si quelqu'un peut m'aider.
Cordialement,
lnj
J'ai des questions à toutes vos réponses. (Woody Allen)
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 -rretourne toujours xxx-generic ? Auquel cas avec un bête
sedle 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
-
Bonjour,
D'aprèsman uname
ce qui correspond le plus à ce que tu cherches estuname -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. Ensuitesed
,grep
ouegrep
sont autant de solutions possibles.
echo $(uname -r) | egrep -o "(([0-9\.]+-)*[0-9\.]+)"
Bonne chance-
Merci :)
Bien legrep -o
pour n'afficher que ce qui correspond, par contreecho ${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 ?
-
-
En terme de portabilité la syntaxe
echo
se discute, car elle pré-suppose que tu fais du bash. La technique avecegrep
est relativement portable et peut être adaptée avecgrep
en mettant des \ aux bons endroits.
Concernant la syntaxe :
-echo ${s%-*}vient à la base deecho $s
ouecho ${s}qui signifie "afficher le contenu de la variables
" ;%
désigne la chaîne à extraire,-
est le séparateur sur lequel on coupe, et*
désigne le reste.
- concernantegrep
, la syntaxe est logique à condition de savoir utiliser des expressions rationnelles (ou régulières), détaillées dansman 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 decat /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 avecuname -r
reste donc plus simple à réaliser.
Bonne chance-
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
Legrep
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 ;)
-
-
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 (genreuname
) car ça t'évite lespopen
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 unecho
et tu regardes sigrep
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 forme1.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