Wie kann ich ein Modul zweimal idecotent installieren?

565
spraff

Ich habe ein Bash-Skript, das wieder ausgeführt werden kann. Es enthält

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

Wenn dies zweimal läuft, wird ein Fehler angezeigt

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

Im Gegensatz zu Tools wie apt-get oder yum gibt pecl einen Fehlercode zurück, wenn das Modul bereits installiert ist. Ich möchte jedoch, dass es über Erfolg berichtet.

Ich könnte Capture aufnehmen und grep stdout / stderr, aber gibt es einen weniger hackigen Weg, um dasselbe zu erreichen?

2
Hervorragende Verwendung des Wortes "idempotently" - musste nachschlagen, beschreibt aber die Situation perfekt. Argonauts vor 7 Jahren 0

2 Antworten auf die Frage

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

Sie könnten diskriminieren und maskieren

Der Rückgabewert des pecl install fooBefehls mit der folgenden Technik. Es speichert den Rückgabewert des Aufrufs, wird jedoch durch den Befehl 'true' maskiert, sodass die Anweisung unabhängig vom Wert von 0 0 zurückgibt retVal.

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

Aber...

Dies wird nicht viel helfen, da der pecl installWert unabhängig von der Art des Fehlers scheinbar auf 1 zurückgegeben wird. Ein Schnelltest hat gezeigt, dass ein bereits installiertes Paket oder ein Fehler, der nicht gefunden wurde, beide 1 zurückgibt.

Stattdessen würde ich einfach prüfen, ob das Paket bereits vor dem Aufruf installiert ist pecl install.

Um zu überprüfen, ob ein Paket installiert ist, gehe ich davon aus, dass der Name nicht das Präfix pecl enthält, z. B. jsonc nicht pecl / jsonc; und dass die Ausgabe von pecl list-all immer mit pecl beginnt. Um zu klären, lassen Sie uns sagen, dass wir mit Paket jsonc arbeiten:

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

Wird zu dieser Ausgabe führen (vorausgesetzt, dass sie installiert ist):

pecl/jsonc 1.3.10 JavaScript Object Notation 

Um zu vermeiden, dass fälschlicherweise ein installiertes Paket deklariert wird, verwendet der für grep verwendete Regex das Ausgabeformat. Wenn wir nur den Paketnamen angleichen, wäre eine Übereinstimmung mit jsonc auch eine Übereinstimmung mit jsoncde (kein echtes Paket). Der Regex sucht also nach dem Zeilenanfang, pecl/dem der Paketname gefolgt wird, mit einem Leerzeichen nach dem Paketnamen:"^pecl/$pkg "

Möglicherweise müssen Sie diesen regulären Ausdruck auf der Grundlage der möglichen verwendeten Paketnamen ändern.

#!/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 

Wenn sich der pecl list-all | grep ...Befehl bei der Suche nach installierten Paketen fehlerhaft verhält, können Sie den Befehl möglicherweise auch verwenden pecl info $pkg. Ich habe mich nicht viel damit befasst, aber es scheint eine 0 (und eine Menge von Informationen an stdout) zurückzugeben, wenn das abgefragte Paket installiert ist, und eine 1, wenn das Paket nicht installiert ist (und ein Fehler an stderr.) ).