Comment puis-je installer deux fois un module?

2

J'ai un script bash qui devrait être ré-exécutable. Il comprend

pecl install foo ||
{
    echo "Could not install foo!";
    exit 1;
}

Si cela fonctionne deux fois, il se trompe

pecl/foo is already installed and is the same as the released version 1.2.3
install failed
Could not install foo!

Contrairement à des outils tels qu'apt-get ou yum, pecl renvoie un code d'erreur si le module est déjà installé, alors que je souhaite qu'il signale le succès.

Je pourrais capturer et grep stdout / stderr mais existe-t-il un moyen moins compliqué d’atteindre le même résultat?

spraff
la source
Excellente utilisation du mot 'idempotently' - dû chercher, mais il décrit parfaitement la situation.
Argonauts

Réponses:

1
if ! pecl list | grep foo >/dev/null 2>&1;
then
    pecl install foo ||
    {
        echo_err "Could not pecl install foo";
        exit 1;
    }
fi
spraff
la source
1

Vous pouvez discriminer sur et masque

la valeur de retour de la pecl install foo commande avec la technique ci-dessous. Il enregistre la valeur de retour de l'appel, mais la commande "true" le masque efficacement, de sorte que l'instruction renvoie 0 quelle que soit la valeur de retVal.

pecl install foo >/dev/null 2>&1 || { retVal=$?; true; }

Mais...

cela n'aidera pas beaucoup, parce que pecl install semble renvoyer une valeur de 1 quelle que soit la nature de l'échec - un test rapide a montré qu'un paquet déjà installé ou une erreur de paquet non trouvé retournera tous les deux 1.

Donc, au lieu de cela, je vérifierais simplement si le paquet est déjà installé avant d'appeler pecl install.

Pour vérifier si un paquet est installé, je suppose que le nom n'inclut pas le préfixe pecl, par exemple. jsonc not pecl / jsonc; et que la sortie de pecl list-all commencera toujours par pecl. Pour clarifier, disons que nous travaillons avec le paquet jsonc:

 pkg="jsonc"
 pecl list-all | grep "$pkg"

Entraînera cette sortie (en supposant qu'elle soit installée):

pecl/jsonc                    1.3.10 JavaScript Object Notation

Pour éviter de déclarer faussement un paquet installé, l'expression rationnelle utilisée avec grep exploite ce format de sortie. Si nous apparions simplement le nom du paquet, une correspondance sur jsonc serait également une correspondance pour jsoncde (pas un vrai paquet). Donc, la regex cherche le début de la ligne pour être pecl/ suivi du nom du paquet, avec un espace après le nom du paquet: "^pecl/$pkg "

Vous devrez peut-être modifier cette expression rationnelle en fonction des noms de package possibles utilisés.

#!/bin/bash

if [ $# -lt 1 ]; then
  echo "Package name must be passed as sole argument"
  exit 2
else
  pkg="$1"
fi

if pecl list-all | grep -Eq "^pecl/$pkg " ; then
  echo "package $pkg is already installed"
  exit 0
else # not installed
  if pecl -q install "$pkg" >/dev/null ; then
    echo "Package $pkg installed successfully"
    exit 0
  else
    echo "Error occurred during installation of $pkg"
    exit 1
  fi
fi

Si la pecl list-all | grep ... commande se comporte mal lors de la recherche de packages installés, vous pouvez également utiliser la commande pecl info $pkg. Je n'ai pas beaucoup étudié la question, mais il semble renvoyer un 0 (et une foule d'informations à stdout) lorsque le paquet demandé est installé, et renvoie un 1 lorsque le paquet n'est pas installé ).

Argonauts
la source