Existe-t-il un outil d'analyse de nom qui fait partie du package d'outils RPM officiel?
J'ai une liste de noms de fichiers. Chacun est le nom de fichier d'un package RPM. Je n'ai pas les paquets réels, juste les noms de fichiers. Pour chacun, j'ai besoin d'extraire le nom et la version du package ($ NAME et $ VERSION). La raison pour laquelle j'en ai besoin est que j'écris un script qui s'assure ensuite que "yum install $ VERSION" installe $ VERSION. Cela fait partie d'un système qui construit des packages et vérifie qu'ils sont correctement téléchargés.
La liste des noms de fichiers ressemble à:
$ cat /tmp/packages.txt
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/emacs-mercurial-el-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/mercurial-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/mercurial-hgk-2.8-3.el6.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/python-redis-2.8.0-2.el6.noarch.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/redis-2.6.16-1.el6.1.x86_64.rpm
/home/builder/packages/testing-dev/CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
J'ai trouvé le code suivant qui est une fonction BASH qui fait la tâche:
function parse_rpm() { RPM=$1;B=${RPM##*/};B=${B%.rpm};A=${B##*.};B=${B%.*};R=${B##*-};B=${B%-*};V=${B##*-};B=${B%-*};N=$B;echo "$N $V $R $A"; }
for i in $(</tmp/packages.txt) ; do
parse_rpm $i
done
Ça marche. La plupart. Il y a quelques exceptions:
$ parse_rpm CentOS/6/x86_64/sei_dnsmaster-1.0-99.el6.x86_64.rpm
sei_dnsmaster 1.0 99.el6 x86_64
Notez qu'il n'a pas obtenu la version correctement (elle devrait être 1.0-99)
Je me demande (1) s'il y a un outil dans le paquetage rpmdev qui le fait correctement. (2) Sinon, y a-t-il une expression officielle que je pourrais utiliser. (3) Quel est l'équivalent python de cette expression régulière?
Merci d'avance!
Réponses:
Vous n'avez pas besoin de faire quoi que ce soit; RPM a un argument de format de requête qui vous permettra de spécifier exactement les données que vous souhaitez recevoir. Il sortira même sans fin de ligne si vous ne les spécifiez pas.
Par exemple:
La liste complète des variables que vous pouvez utiliser peut être obtenue avec:
Notez que dans le cas de
RELEASE
, la sortie like84.el6
est normale et attendue, car c'est en fait la façon dont les packages RPM sont versionnés lorsqu'ils sont empaquetés par ou pour une distribution.la source
$ rpm --queryformat "%{NAME} %{VERSION} %{RELEASE} %{ARCH}" -q CentOS/6/x86_64/sei_dnsmaster-1.0-84.el6.x86_64.rpm package CentOS/6/x86_64/sei_dnsmaster-1.0-84.el6.x86_64.rpm is not installed
libopenssl0_9_8-32bit-0.9.8j-0.26.1_0.50.1.x86_64.delta.rpm
On m'a dit que la manière officielle de faire ce que je cherchais est en Python:
J'ai écrit un petit programme Python qui fait ce dont j'ai besoin. Je proposerai le script au projet rpmdev pour inclusion.
la source
J'ai élaboré des expressions régulières qui correspondent à toutes les données avec lesquelles j'ai pu les tester. J'ai dû utiliser un mélange de matchs gourmands et non gourmands. Cela dit, voici mes versions perl et python:
Perl:
Python:
Je préfère avoir une expression régulière qui provient du projet RPM. Celui que j'ai inventé ci-dessus devra faire pour l'instant.
la source
.*
moins que vous ne vouliez VRAIMENT correspondre à quoi que ce soit). C'est bien de voir que vous l'avez trouvé par vous-même!AdbeRdr9.5.5-1_i486linux_enu.rpm
) qui rompt l'analyse syntaxique ci-dessus.Les fichiers RPM peuvent avoir des noms de fichiers géniaux dans les cas extrêmes, mais généralement vous pouvez diviser le NVR sur les tirets. Le hic est que la partie N (nom) du NVR peut contenir des traits d'union et des traits de soulignement, mais les V (version) et R (version) sont garantis de ne pas avoir de tirets étrangers. Vous pouvez donc commencer par rogner la partie VR pour dériver un nom.
En s'appuyant sur cela, vous pouvez isoler la partie version et version.
Il suffit de diviser à nouveau le tiret pour isoler la pièce dont vous avez besoin. Et évidemment, nettoyez les chaînes d'extension de fichier arch et rpm, ce qui est un fait. Je vous donne juste une idée de la façon dont cela pourrait être abordé en bash.
la source
Utilisez les options -q --queryformat de rpm comme indiqué précédemment, si vous voulez le faire sur un paquet non installé, vous pouvez spécifier le rpm avec l'
-p
option, comme ceci:par exemple
Donne moi
il suffit donc de diviser le nom de fichier!
alors faites attention , ce ne sont pas les détails corrects du régime, par exemple, il
1.fedora
est en fait1.fc10
dans le régime.la source
Si vous connaissez les expressions régulières et / ou Perl, c'est assez simple.
ou le regex seul:
Si vous le divisez, c'est:
[^\-]+
trait d' union, au moins un caractère: (échappé car le trait d'union a une signification particulière dans les groupes de caractères)[^\-]+?
([^\-]+?)
([^\-]+?)-
.rpm
):([^\-]+?)-(.*).rpm$
(le dollar signifie "fin de ligne")m#([^\-]+?)-(.*).rpm$#
Terminé ! Obtenez simplement les deux parties dans les variables
$1
et$2
Commentaire sur le premier one-liner:
J'étais dans un répertoire contenant de nombreux fichiers rpm, d'où le
ls
.perl -p
est équivalent à ;Ce qui explique que j'ai dû mettre une chaîne nulle
$_
pour éviter que perl n'imprime la ligne après l'avoir extraite et imprimée sur mesure. Notez que j'aurais pu utiliser des substitutions pour éviter ce petit «hack».la source
module-init-tools-3.9-21.el6_4.x86_64.rpm
.À mon humble avis, la manière la plus simple de shell est:
C'est-à-dire: inverser chaque ligne, en utilisant la coupe oblique uniquement la première partie ( emanelif ), puis en utilisant la coupure de trait d'union, sauf les deux premières parties (c'est-à-dire laisser derrière ESAELER, y compris emanelif eth fo tser et NOISREV ) et inverser l' énil en arrière.
Avec votre fichier d'exemple:
Pour obtenir d'autres pièces, il faut exercer la lecture de la coupe (1) .
la source
Vous pouvez utiliser
dnf info
. Voici un exemple de script Bash pour obtenir des valeurs et définir en tant que variable:Cela donnera un résultat même si le paquet n'est pas installé.
la source