staging.inyokaproject.org

Vergleich von Zahlen

Status: Ungelöst | Ubuntu-Version: Kubuntu 16.04 (Xenial Xerus)
Antworten |

5kyy

Anmeldungsdatum:
27. Juli 2009

Beiträge: 284

Hallo,

ich hab ein Script, welches mir die PHP Versionen aktualisiert. Nun hab ich heute festgestellt, dass das Script mir trotz verfügbarem Update anzeigt, dass kein Update notwendig ist.

Ursache ist dass inzwischen PHP 7.0.10 herauskam, die Installierte Version 7.0.9 ist.

Der Vergleich:

if [[ $installed_version < $available_version ]]
then
    macheupdate...
else
    nicht notwendig...
fi

liefert also ein false da wohl die Installierte Version größer ist. Beachtet man die Null am Ende von 7.0.10 nicht, stimmt das auch, dass 7.0.9 größer ist.

*lach* Wie kann ich sicherstellen, dass hier ein Update stattfindet?

Habs gerade mit:

if [[ ! $installed_version == $available_version ]]
then
    macheupdate...
else
    nicht notwendig...
fi

gelöst, aber das finde ich nicht schön, denn sollte mal die verfügbare Version nicht gelesen werden können (Server down?) würde er mir ein True liefern und den Update Prozess versuchen.

LG

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17432

Entweder bash sortiert hier alphabetisch, da ist aber 9 > 10, da 9>1 verglichen wird, also zeichenweise.

Oder bash versucht es numerisch (lt?), das scheitert aber an zwei Punkten.

Sort kommt mit einem fertigen Versionsvergleich

-V, --version-sort natürliche Ordnung von Versionsnummern innerhalb des Textes

so dass

1
echo -e "1.0.9\n1.0.10" | sort -V

funktioniert,

1
echo -e "1.0.9\n1.0.10" | sort -V | tail -n 1 

liefert davon die letzte Zeile, also vergleichst Du die auf Gleichheit mit Deiner Version.

1
latest=$(echo -e "1.0.9\n1.0.10" | sort -V | tail -n 1)

Oder Du schreibst Dir eine Funktion für den Vergleich selbst, zur Übung.

5kyy

(Themenstarter)

Anmeldungsdatum:
27. Juli 2009

Beiträge: 284

boah Respekt. Vielen Dank.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

user_unknown schrieb:

1
echo -e "1.0.9\n1.0.10" | sort -V | tail -n 1 

Für den aktuellen Fall ist es völlig irrelevant, aber ich fand den Gedanken interessant, ob diese Version von Dir oder folgende im Schnitt (also auch bei Betrachtung sehr großer Eingaben) schneller ist:

1
echo -e "1.0.9\n1.0.10" | sort -Vr | head -n 1

Der Vorteil von head ist ja, dass es nicht die gesamte Eingabe aus der Pipe lesen muss, sondern nach der ersten Zeile bereits aufhören kann, wohingegen tail bei einer Pipe tatsächlich alles lesen muss, um die letzte Zeile auszugeben. Der sort wird keinen Unterschied machen, denn er muss unabhängig von der Sortierreihenfolge immer die gesamte Eingabe lesen.

Ich habe das mal ausprobiert...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ LC_NUMERIC=C seq -f '10.%.1f' 1 160000000 >|x
$ du -h x
2,2G	x
$ head -5 x
10.1.0
10.2.0
10.3.0
10.4.0
10.5.0
$ tail -5 x
10.159999996.0
10.159999997.0
10.159999998.0
10.159999999.0
10.160000000.0
$ time { sort -V x | tail -1; }
10.160000000.0

real	4m1.385s
user	6m8.540s
sys	0m10.684s
$ time { sort -Vr x | head -1; }
10.160000000.0

real	3m38.959s
user	6m18.328s
sys	0m8.000s
$ time { sort -V x | tail -1; }
10.160000000.0

real	4m13.180s
user	6m16.440s
sys	0m13.664s
$ time { sort -Vr x | head -1; }
10.160000000.0

real	3m49.041s
user	6m13.484s
sys	0m8.832s

In beiden Fällen ist die Version mit head ca. 10% schneller, was zu einem Teil auf IO zurückgeht (siehe auch Zeiten für "sys") und vermutlich (weil die Zahlen in dieser kleinen Stichprobe zu uneinheitlich sind) auch auf CPU in tail.

Das wollte ich immer mal ausprobiert haben. 😉

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Für den Vergleich wird man das Sortierergebnis doch sowieso in eine Variable hinein substituiert, oder ?

Dann kann man sich das head oder tail auch sparen und eine Array-Zerlegung nehmen:

track@track:~$ v_i=7.0.9
track@track:~$ v_a=7.0.10
track@track:~$ v_max=( $(echo -e "$v_i\n$v_a" | sort -rV ) )
track@track:~$ echo $v_max
7.0.10
track@track:~$ v_a=
track@track:~$ v_max=( $(echo -e "$v_i\n$v_a" | sort -rV ) )
track@track:~$ echo $v_max
7.0.9 

Damit bleibt der Vergleich von $v_max != $v_i oder $v_max == $v_a auch stabil, wenn was schief geht.

LG,

track

p.s.:
Oder noch schöner:

track@track:~$ v_a=7.0.10
track@track:~$ echo -e "$v_i\n$v_a" | sort -cV ; echo $?
0
track@track:~$ v_a=
track@track:~$ echo -e "$v_i\n$v_a" | sort -cV ; echo $?
sort: -:2: ungeordnet: 
1 

also praktisch dann wohl so:

1
2
3
if ! echo -e "$v_a\n$v_i" | sort -cV  2> /dev/null;  then
    echo update
fi
Antworten |