Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 19/12/2024, à 17:15

cristobal78

Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Bonjour à tous

je suis en train de relire d'anciens scripts et je cherche à les améliorer où à les simplifier ou ... les deux.
En particulier, j'utilise souvent dans mes scripts une fonction destinée à m'assurer que les paquets nécessaires au bon déroulement d'un script sont bien installés sur le PC.

Cette fonction c'est :

{
for paquet in $1
do
	dpkg-query -l | grep -qE "^.i *$paquet" 2> /dev/null 	# si installé alors ligne avec un "i" en 2-ème car.
	code=$?
	if [ $code -ne 0 ] ; then zenity --error --title="" --text="$2" ; exit ; fi
done
}

Un ami a attiré mon attention en me disant  "il doit y avoir plus simple avec la commande which"

Donc j'ai fait quelques essais et j'avoue que je ne comprends pas le fonctionnement de cette commande.
En effet via synatic j'ai repéré 4 paquets au hasard marqués (cochés) 2 comme installés et 2 non cochés donc en principe pas installés.

Voici 4 paquets :
cochés :
acl
apg

non cochés :
acl2
acr

et essayé la commande which :

moi@ldlcfixe22p:~$ which acl
moi@ldlcfixe22p:~$ which apg
/usr/bin/apg
moi@ldlcfixe22p:~$ which acl2
moi@ldlcfixe22p:~$ which apr

moi@ldlcfixe22p:~$ which acl | echo $?
0
moi@ldlcfixe22p:~$ which apg | echo $?
0
moi@ldlcfixe22p:~$ which acl2 | echo $?
0
moi@ldlcfixe22p:~$ which apr | echo $?
130
moi@ldlcfixe22p:~$ 

J'avoue que je ne sais pas interpréter ces résultats !
Qu'en pensez vous ?


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#2 Le 19/12/2024, à 17:20

sputnick

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Salut:

for pkg in "$@"; do
    if dpkg -l "$pkg" &>/dev/null; then
        echo "$pkg installed"
    else
        echo "$pkg NOT installed"
    fi
done

Je sais, un peu partout, tout le monde s'entretue, c'est pas gai, mais d'autres s'entrevivent, j'irai les retrouver.
https://sputnick.fr

Hors ligne

#3 Le 19/12/2024, à 19:22

Watael

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

il serait bon de distinguer si tu veux vérifier qu'un programme est disponible sur ta machine pour être exécuté dans un script, ou si tu cherches à savoir qu'un paquet est installé.
ce ,'est pas exactement la même chose : un paquet peut contenir plusieurs programmes sans que son nom reflète celui du/es programme(s) (utils-linux, par exemple).


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#4 Le 19/12/2024, à 19:40

Tawal

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Hello,

Comme le souligne Watael, il y a une différence entre un paquet et une commande.

Mais si on cherche à s'assurer qu'une commande externe est disponible,
alors autant utiliser hash qui a l'avantage de mettre le chemin d'accès à la commande dans une table de hashage.
La syntaxe :

if ! hash   la_commande  2>/dev/null
then
   # traitement en cas d'inexistence de   la_commande
fi

Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#5 Le 19/12/2024, à 19:50

RaphaelG

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

which recherche dans ta variable d'environnement PATH si le nom de fichier passé en argument est présent et si il l'est alors il l'affiche.

~$ which toto
~$ echo $?
1
~$ which which
/usr/bin/which
~$ echo $?
0
~$ 

Ton idée de piper le résultat de which sur un echo, j'avoue que je ne sais pas bien ce que ça fait mais ça ne fait sûrement pas ce que tu espérais.

dpkg-query est une commande bas niveau, elle même utilisée par dpkg.
Il vaut mieux utiliser dpkg qui est plus user friendly. Le code de sputnick est parfait si on veut vérifier au niveau paquet.

hash n'est pas installé chez moi. C'est quel paquet ?

Hors ligne

#6 Le 19/12/2024, à 19:54

Tawal

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

RaphaelG a écrit :

hash n'est pas installé chez moi. C'est quel paquet ?

$ type hash
hash est une primitive du shell

Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#7 Le 19/12/2024, à 20:10

ylag

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Bonsoir,

sputnick a écrit :

Salut:

for pkg in "$@"; do
    if dpkg -l "$pkg" &>/dev/null; then
        echo "$pkg installed"
    else
        echo "$pkg NOT installed"
    fi
done

On me corrigera s'il y a lieu, mais pour s'assurer que le paquet soit correctement installé, faudrait-il vérifier que la ligne du retour de dpkg -l "$pkg" débute par ii ?

A+

Dernière modification par ylag (Le 19/12/2024, à 20:11)

Hors ligne

#8 Le 19/12/2024, à 20:10

RaphaelG

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

ha ouais, c'est du bashisme.
Marci Tawal.

Hors ligne

#9 Le 19/12/2024, à 20:14

cristobal78

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

bonsoir à sputnick, watael, tawal, raphael  qui sont toujours là !

Alors merci à Sputnick pour sa proposition un peu moins lourde que la mienne et à raphael pour sa précision.
A ylag : mon script vérifie justement les "ii".

Pour tenter de répondre à watael voici le genre d'objet (je dis "objet" car je ne suis sûr de moi quant à leur exacte signification !) dont je teste la disponibilité dans le corps de mes scripts :
ghostscript
enscript
unoconv
ccrypt
imagemagick (car je vais utiliser convert)
pdfposter
rename
ffmpeg
pdftk
lame

Évidement tous ces "objets" sont disponibles sur mon pc mais si je donne un de mes scripts à quelqu'un il faut bien que ce script le prévienne - éventuellement - qu'il manque certains "objets" sur son PC pour que mon script s'exécute correctement chez lui.

L'idée c'est donc d'envoyer, en cas de manque, un message du genre : "Attention, ce script nécessite la présence de ffmpeg".

D'où ma question du post initial : which est-il un bon outil pour cela ?

Dernière modification par cristobal78 (Le 19/12/2024, à 20:17)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#10 Le 19/12/2024, à 20:29

Tawal

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Ma réponse est : hash est mieux pour tester la présence d'une commande externe.
Il suffit d'indiquer le nom du paquet contenant la commande manquante.


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#11 Le 20/12/2024, à 02:04

cristobal78

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@ tawal

autrement dit  hash permet de contrôler aussi bien les paquets que les commandes c'est bien ça ?

Voilà ce que j'ai testé :

moi@ldlcfixe22p:~$ if ! hash  firefox  2>/dev/null; then    echo "commande ou paquet introuvable"; fi
moi@ldlcfixe22p:~$ 

pas de réaction, la commande ne retourne que le prompt, donc Firefox est présent
tandis que :

moi@ldlcfixe22p:~$ if ! hash  firefoxtrot  2>/dev/null; then    echo "commande ou paquet introuvable"; fi
commande ou paquet introuvable
moi@ldlcfixe22p:~$ 

car le paquet firefoxtrot n'est pas là ou n'existe pas.


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#12 Le 20/12/2024, à 04:12

sputnick

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

ylag a écrit :

Bonsoir,

On me corrigera s'il y a lieu, mais pour s'assurer que le paquet soit correctement installé, faudrait-il vérifier que la ligne du retour de dpkg -l "$pkg" débute par ii ?

Le mieux c'est de tester pour s'en assurer:

$ dpkg -l curl &>/dev/null && echo installed || echo NOT installed
installed
$ dpkg -l curlX &>/dev/null && echo installed || echo NOT installed
NOT installed

Pense tu que je partagerai quelque chose qui ne fonctionne pas?


Je sais, un peu partout, tout le monde s'entretue, c'est pas gai, mais d'autres s'entrevivent, j'irai les retrouver.
https://sputnick.fr

Hors ligne

#13 Le 20/12/2024, à 10:30

Tawal

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@cristobal78 :
Non, hash ne contrôle que la présence de la commande donnée en argument.
Elle retourne un code retour 0 si la commande existe dans le PATH sinon 1.
Si la commande est dans le PATH, hash met son chemin d'accès dans une table de hashage dédiée au shell en cours.

Si la commande est manquante, il faut indiquer le paquet (à toi de le connaître) permettant d'installer la commande manquante.
Exemple avec tail venant du paquet coreutils :

if ! hash tail 2>/dev/null
then
   echo "Requiert la commande 'tail'. Installez le paquet 'coreutils'."
   exit 1
fi

Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#14 Le 20/12/2024, à 11:41

cristobal78

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@ tawal
Tu dis :
Non, hash ne contrôle que la présence de la commande donnée en argument.

et pas les paquets ?

Pourtant dans mon dernier post (# 11) je lance ta ligne de commande avec hash et elle détecte bien quele paquet firefox est bien présent alors qu'elle voit bien que firefoxtrot n'est pas sur le pc (évidement !!)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#15 Le 20/12/2024, à 11:46

iznobe

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

oui , sauf que "firefox " est aussi une commande ...
il detecte la commande et pas le paquet .

essaie :

firefox

Pour t ' en assurer .



tu fais toujours la confusion :

Watael a écrit :

il serait bon de distinguer si tu veux vérifier qu'un programme est disponible sur ta machine pour être exécuté dans un script, ou si tu cherches à savoir qu'un paquet est installé.
ce ,'est pas exactement la même chose : un paquet peut contenir plusieurs programmes sans que son nom reflète celui du/es programme(s) (utils-linux, par exemple).

:

Dernière modification par iznobe (Le 20/12/2024, à 11:52)


retour COMPLET et utilisable de commande
MSI Z490A-pro , i7 10700 , 32 GB RAM .

Hors ligne

#16 Le 20/12/2024, à 12:14

Tawal

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@cristobal:
Est-ce tu vois la différence ainsi :

$ hash tail
$ echo $?
0
$ hash coreutils
bash: hash: coreutils : non trouvé
$ echo $?
1
$

hash ne contrôle que la commande (tail existe mais pas coreutils en tant que commande)


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#17 Le 20/12/2024, à 12:37

cristobal78

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@ iznobe

oui tu as raison  smile  j'ai fait cette confusion et, comme tu le rappelles fort justement, le mot firefox est les 2 à la fois : quand on tape le mot firefox dans un terminal c'est une commande et c'est elle qui active le paquet du même nom.
Ce coup là c'est clair dans mon esprit.

Dans mon post initial je disais :
" .... une fonction destinée à m'assurer que les paquets nécessaires au bon déroulement d'un script sont bien installés sur le PC".
J'aurais sans doute dû écrire :
" .... une fonction destinée à m'assurer que les paquets ET LES COMMANDES nécessaires au bon déroulement d'un script sont bien installés sur le PC".

ce qui devrait répondre à la judicieuse remarque de watael :

"... il serait bon de distinguer si tu veux vérifier qu'un programme est disponible sur ta machine pour être exécuté dans un script, ..."

En résumé je veux m'assurer que le script ne se plante pas du fait absence d'une quelconque commande ou d'un quelconque paquet.

Donc si mon script utilise convert ou identify (par exemple) ce n'est pas convert ou identify dont il faut tester l'existence mais au contraire celle du paquet imagemagick.
C'est bien ça ?

Si oui  alors quel est le meilleur test ? dpkg ? which ? ...

___________________________
Ah zut ! je n'avais pas vu le dernier  post de tawal  roll

Dernière modification par cristobal78 (Le 20/12/2024, à 12:38)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#18 Le 20/12/2024, à 12:46

RaphaelG

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@sputnick
Ca marche pas si bien que ça, ton truc. Ca ne détecte pas les paquets non purgés ou cassés.
Par exemple, chez moi, suite au passage au noyau 6.8.0-51 :

dpkg$ dpkg -l | grep -v ^ii | sed '1,5d'
rc  linux-image-6.8.0-48-generic                  6.8.0-48.48                              amd64        Signed kernel image generic
rc  linux-image-6.8.0-49-generic                  6.8.0-49.49                              amd64        Signed kernel image generic
rc  linux-modules-6.8.0-48-generic                6.8.0-48.48                              amd64        Linux kernel extra modules for version 6.8.0 on 64 bit x86 SMP
rc  linux-modules-6.8.0-49-generic                6.8.0-49.49                              amd64        Linux kernel extra modules for version 6.8.0 on 64 bit x86 SMP
rc  linux-modules-extra-6.8.0-48-generic          6.8.0-48.48                              amd64        Linux kernel extra modules for version 6.8.0 on 64 bit x86 SMP
rc  linux-modules-extra-6.8.0-49-generic          6.8.0-49.49                              amd64        Linux kernel extra modules for version 6.8.0 on 64 bit x86 SMP
dpkg$ dpkg -l linux-image-6.8.0-48-generic &>/dev/null && echo installed || echo NOT installed
installed
dpkg$

Alors que manifestement le paquet linux-image-6.8.0-48-generic a été en partie désinstallé

Je vous propose cela :

#!/bin/sh
# 1 seul argument : le nom du paquet à vérifier

dpkg -l $1 >/dev/null 2>&1
rc=$?
if [ $rc -ne 0 ]
then echo "$1 not installed"
else
    dse=`dpkg -l $1 | awk 'FNR == 6 { print $1 }'`
    if [ "$dse" = ii ]
    then echo "$1 installed"
    else
        echo "$1 badly installed"
        rc=2
    fi
fi
exit $rc

C'est plus ou moins POSIX mais ça marche aussi avec bash.
Ah, ah, je m'aperçois que j'ai plus de ligne que cristobal78 en #1. Je vais dire que c'est parce que je gère mieux les codes retour.

De toute de manière, le jeu reste ouvert car on ne traite pas les applis en snap (ou en flatpak ou en Appimage). Par exemple, le paquet .deb pdftk n'existe plus en 24.04 et doit être installé en snap.
J'essaye de faire un truc bourré de bashismes avec des tableaux et  hash comme conseillé par Tawal. Mais comme je suis nul en bash, ça me prend du temps.

@cristobal: le meilleur est hash puisque c'est Tawal qui le dit.

Hors ligne

#19 Le 20/12/2024, à 12:50

cristobal78

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@ tawal

Merci pour ton exemple.
Donc si on veut utiliser tail dans un script il faut s'assurer que coreutils est installé. Inutile de tester la présence de tail.
Le problème c'est que ce n'est pas évident de savoir que tail comme cat, chmod, echo font partie de ce paquet.

Idem pour convert : vérifier que le paquet imagemagick est installé devrait suffire.

Dernière modification par cristobal78 (Le 20/12/2024, à 12:55)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#20 Le 20/12/2024, à 12:54

cristobal78

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

@ raphaelG

j'aime bien ta remarque :

"Ah, ah, je m'aperçois que j'ai plus de ligne que cristobal78 en #1. Je vais dire que c'est parce que je gère mieux les codes retour."  smile smile smile


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#21 Le 20/12/2024, à 13:07

diesel

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

RaphaelG a écrit :

De toute de manière, le jeu reste ouvert car on ne traite pas les applis en snap (ou en flatpak ou en Appimage). Par exemple, le paquet .deb pdftk n'existe plus en 24.04 et doit être installé en snap.

Un défaut de plus pour snap (ou flatpack). sad

Amicalement.

Jean-Marie


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

Hors ligne

#22 Le 20/12/2024, à 13:42

RaphaelG

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Un boomer s'essaye au bash.

#!/bin/bash

declare -a File
File=( [0]=ghostscript [1]=ensscript [2]=unoconv [3]=ccrypt [4]=convert 
[5]=pdfposter [6]=rename [7]=ffmpeg [8]=pdftk [9]=lame )
declare -a App
App=( [0]=ghostscript [1]=ensscript [2]=unoconv [3]=ccrypt [4]=imagekick
[5]=pdfposter [6]=arename [7]=ffmpeg [8]=pdftk [9]=lame )
declare -a appFormat  # d=debian package, s=snap
appFormat=( [0]=d [1]=d [2]=d [3]=d [4]=d [5]=d [6]=d [7]=d [8]=s [9]=d )

itmp=${#File[*]}
(( imax = itmp - 1 ))
for i in $(seq 0 $imax)
do
    hash ${File[$i]} >/dev/null 2>&1
    rc=$?
    if [ $rc -ne 0 ]
    then
        case "${appFormat[$i]}" in
            d ) echo "Please, install the Debian package ${App[$i]}"
            ;;
            s ) echo "Please, install the snap ${App[$i]}"
            ;;
        esac
    fi
done

Je voulais déclarer mes tableaux en read only et ne pas utiliser la variable intermèdiaire itmp mais j'ai pas su faire.

Dernière modification par RaphaelG (Le 20/12/2024, à 13:43)

Hors ligne

#23 Le 20/12/2024, à 14:15

RaphaelG

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

J'ai trouvé comment déclarer les tableaux en read only :

declare -ra File=( [0]=ghostscript [1]=ensscript [2]=unoconv [3]=ccrypt
[4]=convert [5]=pdfposter [6]=rename [7]=ffmpeg [8]=pdftk [9]=lame )

Hors ligne

#24 Le 20/12/2024, à 15:14

Tawal

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

Personnellement, je ne teste que les commandes externes.
Car il est aussi possible qu'une même commande soit fournie par des paquets différents (j'ai pas d'exemple mais ça existe).
Mais chacun l'entend comme il veut.


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#25 Le 20/12/2024, à 15:58

RaphaelG

Re : Vérifier qu'un paquet est installé ou pas : which, dpkg avec grep ?

On est bien obligé de tester le retour de hash pour savoir si l'argument est un fichier de ton PATH ou pas. Je vais m'inspirer de ton post #13 :

#!/bin/bash

declare -ra File=( [0]=ghostscript [1]=ensscript [2]=unoconv [3]=ccrypt
[4]=convert [5]=pdfposter [6]=rename [7]=ffmpeg [8]=pdftk [9]=lame )
declare -ra App=( [0]=ghostscript [1]=ensscript [2]=unoconv [3]=ccrypt
[4]=imagekick [5]=pdfposter [6]=arename [7]=ffmpeg [8]=pdftk [9]=lame )
declare -ra appFormat=( [0]=d [1]=d [2]=d [3]=d [4]=d [5]=d [6]=d [7]=d [8]=s
[9]=d )  # d=Debian package, s=snap, f=flatpak, A=Appimage ...


itmp=${#File[*]}
(( imax = itmp - 1 ))
for i in $(seq 0 $imax)
do
    if ! hash ${File[$i]} >/dev/null 2>&1
    then
        case "${appFormat[$i]}" in
            d ) echo "Please, install the Debian package ${App[$i]}"
            ;;
            s ) echo "Please, install the snap ${App[$i]}"
            ;;
        esac
    fi
done

Il me reste plus qu'à éliminer la variable itmp et je considérerai ce script comme parfait.

Dernière modification par RaphaelG (Le 20/12/2024, à 16:06)

Hors ligne