Bash: Ganzzahliger Ausdruck erwartet mit read / test

7

Ich lerne die Grundlagen der Shell-Programmierung, also habe ich etwas Einfaches wie geschrieben

#!/bin/bash
read var1
read var2
if [ var1 -lt var2 ]; then
    echo "var1 is lt var2"
else
    echo "var2 is lt var1"
fi

Ich verstehe, dass Variablen in Bash untypisiert sind und dass jede Variable als Ganzzahl verwendet werden kann, wenn sie nur Ziffern enthält. Aber ich bekomme den Fehler "Integer-Ausdruck erwartet", wenn ich das ausführe ... warum?

Gilles 'SO - hör auf böse zu sein'
quelle

Antworten:

11

Tatsächlich können Sie einige Attribute für Variablen mithilfe des declare(oder des alten typeset) integrierten Systems festlegen. declare -i var1 var2setzt ein ganzzahliges Attribut für diese Variablen. Danach führen Zuweisungen, die versuchen, nicht ganzzahlige Werte für diese Variablen festzulegen, zu Fehlern.

Ihr Problem liegt jedoch in der Syntax. Wenn Sie den Wert einer Variablen verwenden, müssen Sie ihrem Namen Folgendes voranstellen $:

if [ "$var1" -lt "$var2" ]; then
    echo "$var1 is lt $var2"
else
    echo "$var2 is lt $var1"
fi

Ausnahmen sind die arithmetischen Auswertungen, bei denen Folgendes nicht erforderlich ist $:

if ((var1<var2)); then
    echo "$var1 is lt $var2"
else
    echo "$var2 is lt $var1"
fi

Als Wort der Warnung, innen [.. ]zitieren immer doppelt Ihre Variablen zu Wort Expansion vermeiden Ihren Ausdruck Syntax vermasselt. (Ich meine, Sie werden Probleme mit nicht gesetzten Variablen, Variablen mit leeren Zeichenfolgen und Variablen mit IFSZeichen haben.) Oder Sie können die neuere und bessere verwenden [[. ]]Stattdessen werden solche Fälle korrekt behandelt:

if [[ $var1 -lt $var2 ]]; then
    echo "$var1 is lt $var2"
else
    echo "$var2 is lt $var1"
fi
Mann bei der Arbeit
quelle
Auch [[ $var1 < $var2 ]]ist ein String-Vergleich , kein arithmetischer Vergleich ... [[ 11 > 2 ]]Tests als falsch ... [[ 11 -gt 2 ]]Tests als wahr
Peter.O
@ Peter.O, du hast recht. Da ich für numerische Vergleiche nur arithmetische Auswertungen verwende, habe ich das vergessen. Vielen Dank.
Manatwork
1

Sie sollten auf Variablen verweisen, denen der Name vorangestellt ist $

if [ $var1 -lt $var2 ] ; then...
Jari Laamanen
quelle
Und Sie sollten diese Variablen zitieren, es "$var1" -lt "$var2"sei denn, Sie haben einen sehr guten Grund, dies nicht zu tun.
Roaima