Bash-Skript-Case-Anweisung einschließlich Testbedingungen verhält sich nicht

Bash-Skript-Case-Anweisung einschließlich Testbedingungen verhält sich nicht

Ich habe ein ziemlich langes Skript (Hauptskript). Ich werde es hier vollständig einfügen, da ich glaube, dass es für die Antwort relevant sein könnte, also seien Sie bitte nicht so ekelhaft. Alles in diesem Skript funktioniert. Das einzige, womit ich Probleme habe, sind die Fälle *www1) und *www2) am Ende, die im Wesentlichen gleich sind. Der NULL-Test funktioniert und die in die Zenity-Felder eingegebenen Daten werden für diese Fälle korrekt verarbeitet. Wenn ich jedoch nichts in die entsprechenden Zenity-Felder eingebe (Rechnungsnummer und Notiz), else until [[ -n "${var2}" ]]; do...wird dies ignoriert. Am Ende des Skripts habe ich ein weiteres, vereinfachtes Skript nur für den betreffenden Fall eingefügt (vereinfacht). Wenn ich es ausführe, gibt es kein Problem und alles funktioniert wie erwartet. Der Fall ist einfach vom Original kopiert, also reißt es mich die Haare aus, warum das eine funktioniert, das andere aber nicht. Ist jemand bereit, dabei zu helfen?

Das Hauptskript:

#!/bin/bash


work_number="$(zenity --entry --text "ENTER number of work/job entries:" --entry-text "1")"
        a=1

until
        [[ $work_number -lt $a ]]
do

input="$(zenity --forms --title="table work" --text="Add a new job" --separator="," \
       --add-entry="ENTER clientid: " \
       --add-entry="ENTER job_start, -t time without time zone, e.g. '11:45:00', seconds allways zero: " \
       --add-entry="ENTER job_finish, -t time without time zone, e.g. '11:45:00', seconds allways zero: " \
       --add-entry="ENTER number_catchers, -t numeric, must be 0 if no waste has been collected or NULL if it has yet to be assigned to a tip run: " \
       --add-entry="ENTER mower_front, -t numeric:" \
       --add-entry="ENTER mower_back, -t numeric: " \
       --add-entry="ENTER categoryid: " \
       --add-entry="ENTER price, -t numeric: " \
       --add-entry="ENTER invoice_number, -t text: " \
       --add-entry="ENTER note, -t text: " \
       --add-entry="ENTER a tip_runid, -t integer: ")"

psql -tA -U chh1 -d crewdb -c "SELECT SETVAL('work_workid_seq', (SELECT MAX(workid) FROM work), true);" >/dev/null 2>&1
dlink="$(psql -tA -U chh1 -d crewdb -c "SELECT MAX(date_linkid) FROM date_link;")"

startt="$(echo "$input" | awk -F, -v  OFS=, '{print $2}')"
finisht="$(echo "$input" | awk -F, -v  OFS=, '{print $3}')"

st="$( date --date="$startt" +%s  2>/dev/null )"
ft="$( date --date="$finisht" +%s 2>/dev/null )"

if [ -n "$st" -a "$ft" ] ; then

    startt="$(date +%H:%M  -d "$startt"  )"
    finisht="$(date +%H:%M -d "$finisht" )"
    tzdiff="$(( ft - st ))"
else
    tzdiff=0
fi

while [[  ( ( ! "$startt"   =~ ^[0-1][0-9]:[0-5][0-9]$ ) && ( ! "$startt"  =~ ^[0-2][0-3]:[0-5][0-9]$ ) ) ||
          ( ( ! "$finisht"  =~ ^[0-1][0-9]:[0-5][0-9]$ ) && ( ! "$finisht" =~ ^[0-2][0-3]:[0-5][0-9]$ ) ) ||
          ( "$tzdiff" -le 0 )  ]];
do
    var2="$(zenity --forms --title="job start time and/or job finish time are incorrect" --text "Add a job start time and finish_time"  --separator="," \
                   --add-entry="WARNING! Something went wrong. Please enter a valid job start time, e.g. 8:20: " \
                   --add-entry="WARNING! Something went wrong. Please enter a valid job finish time, e.g. 12:30: ")"
    tzdiff=0

    if [ -n "$var2" ] ; then
       b1=$(echo "$var2" | cut -d, -f1 )
       b2=$(echo "$var2" | cut -d, -f2 )

       if [ -n "$b1" -a -n "$b2"  ] ; then
           tz1=$( date --date="$b1" +%s 2>/dev/null )
           tz2=$( date --date="$b2" +%s 2>/dev/null )

           if [ -n "$tz1" -a -n "$tz2" ] ; then
              startt=$(date +%H:%M -d "$b1" )
              finisht=$(date +%H:%M -d "$b2" )
              tzdiff=$(( tz2 - tz1 ))
           fi
       fi
    fi
done

var2="$startt,$finisht"

input="$( echo "$input" | awk -v vard="$dlink" -v vart="$var2" 'BEGIN {  FS="," } { print $1"xxx1" "," vard"ddd" "," vart "," $4"xxx2" "," $5"xxx3" "," $6"xxx4" "," $7"xxx5" "," $8"xxx6" "," $9"www1" "," $10"www2" "," $11"xxx7" ; }' )"

IFS=, read -ra array1 <<<"$input"
out=""

for i in "${array1[@]}"; do

        case "$i" in
        *ddd) out="$out,${i/%ddd/}";;
            
        *xxx1)  if [[ "${i/%xxx1/}" =~ ^[0-9]+$ ]]; then
                
                out="$out,${i/%xxx1/}"

                elif [[ "${i/%xxx1/}" = NULL ]]; then

                    out="$out,${i/%xxx1/}"

                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="clientid field in table work" --text "Add a clientid"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a clientid or didn't enter a number. Please enter a valid clientid: ")"

                                    done

                                    out="$out,${var2}"

                fi  
            
                ;;

        *xxx2) if [[ "${i/%xxx2/}" =~ ^[0-9]+([.][0-9]+)?$ ]]; then

                                out="$out,${i/%xxx2/}"

                                elif [[ "${i/%xxx2/}" = NULL ]]; then

                                        out="$out,${i/%xxx2/}"

                                else    until [[ ${var2} =~ ^[0-9]+([.][0-9]+)?$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="number of catchers field in table work" --text "Add number of catchers"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter number of catchers or didn't enter a number. Please enter a valid number of catchers: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx3) if [[ "${i/%xxx3/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx3/}"

                                elif [[ "${i/%xxx3/}" = NULL ]]; then

                                        out="$out,${i/%xxx3/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="front mower wheel hight field in table work" --text "Add front mower wheel hight"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a front mower wheel hight or didn't enter a number. Please enter a valid front mower wheel hight: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx4)  if [[ "${i/%xxx4/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx4/}"

                                elif [[ "${i/%xxx4/}" = NULL ]]; then

                                        out="$out,${i/%xxx4/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="back mower wheel hight field in table work" --text "Add back mower wheel hight"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a back mower wheel hight or didn't enter a number. Please enter a valid back mower wheel hight: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx5)  if [[ "${i/%xxx5/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx5/}"

                                elif [[ "${i/%xxx5/}" = NULL ]]; then

                                        out="$out,${i/%xxx5/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="categoryid field in table work" --text "Add a categoryid"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a categoryid or didn't enter a number. Please enter a valid categoryid: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;
            
        *xxx6)  if [[ "${i/%xxx6/}" =~ ^[0-9]+([.][0-9]+)?$ ]]; then

                                out="$out,${i/%xxx6/}"

                                elif [[ "${i/%xxx6/}" = NULL ]]; then

                                        out="$out,${i/%xxx6/}"

                                else    until [[ ${var2} =~ ^[0-9]+([.][0-9]+)?$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="price field in table work" --text "Add price"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter price or didn't enter a number. Please enter a valid price: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx7)  if [[ "${i/%xxx7/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx7/}"

                                elif [[ "${i/%xxx7/}" = NULL ]]; then

                                        out="$out,${i/%xxx7/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="tip_runid field in table work" --text "Add a tip_runid"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a tip_runid or didn't enter a number. Please enter a valid tip_runid: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *ttt) out="$out,'${i/%ttt/}:00'";;

        *www1)  if [[ "${i/%www1/}" = NULL ]]; then

                out="$out,${i/%www1/}"

                elif [[ -n "${i/%www1/}" ]]; then

                    out="$out,\$\$${i/%www1/}\$\$"

                else    until [[ -n "${var2}" ]]; do

                    var2="$(zenity --forms --title="invoice number field in table work" --text "Add a invoice number"  --separator="," \
                                    --add-entry="WARNING! You either forgot to enter a invoice number. Please enter a invoice number or NULL: ")"

                    if [[ "${var2}" = NULL ]]; then

                        out="$out,${var2}"

                    else

                        out="$out,\$\$${var2}\$\$"

                    fi

                done

                fi
                                ;;

        *www2)  if [[ "${i/%www2/}" = NULL ]]; then

                                out="$out,${i/%www2/}"

                                elif [[ -n "${i/%www2/}" ]]; then

                                        out="$out,\$\$${i/%www2/}\$\$"

                                        else 

                                until [[ -n "${var2}" ]]; do

                                var2="$(zenityi --forms --title="note field in table work" --text "Add a note"  --separator="," \
                                --add-entry="WARNING! You either forgot to enter a note. Please enter a note or NULL: ")"

                                        if [[ "${var2}" = NULL ]]; then

                                                out="$out,${var2}"

                                        else

                                                out="$out,\$\$${var2}\$\$"

                                        fi

                done
                
                fi
                                ;;

        *) out="$out,'${i}:00'";;

esac;
done

echo "${out:1}"

let a++

done

Vereinfachtes Skript:

#!/bin/bash

work_number="$(zenity --entry --text "ENTER number of work/job entries:" --entry-text "1")"
        a=1

until
        [[ $work_number -lt $a ]]
do

input="$(zenity --forms --title="table work" --text="Add a new job" --separator="," \
       --add-entry="ENTER a: " \
       --add-entry="ENTER invoice reference field: " \
       --add-entry="ENTER b: ")"

input="$( echo "$input" | awk 'BEGIN {  FS="," } { print $1 "," $2"www1" "," $3 ; }' )"

IFS=, read -ra myarray <<<"$input"
out=""

for i in "${myarray[@]}"; do
        case "$i" in
        

        *www1) if [[ "${i/%www1/}" = NULL ]]; then

      out="$out,${i/%www1/}"

elif [[ -n "${i/%www1/}" ]]; then

      out="$out,\$\$${i/%www1/}\$\$"

else    until [[ -n "${var2}" ]]; do

            var2="$(zenity --forms --title="invoice number field in table work" --text "Add a invoice number"  --separator="," \
            --add-entry="WARNING! You either forgot to enter a invoice number. Please enter a invoice number or NULL: ")"

                    if [[ "${var2}" = NULL ]]; then

                         out="${var2}"

                    else

                         out="\$\$${var2}\$\$"

                    fi

        done

 fi
 ;;
 esac
done

out="${out#,}"
printf 'out=%s\n' "$out"
echo "$out"

let a++

done

Antwort1

Erläuterung

Sie verwenden die var2Variable erneut, ohne sie zu löschen ( unset var2) oder ihr einen leeren String zuzuweisen ( var2=''). Daher until [[ -n "${var2}" ]]; do …; donewerden einige altenicht leerWert und der Code anstelle von wird nie ausgeführt.

Im vereinfachten Skript var2ist noch nicht festgelegt, wenn Sie zum ersten Mal zu gelangen until [[ -n "${var2}" ]]; do. Das ist der Unterschied.

Fragen Sie sich jedes Mal, wenn Sie schreiben, until [[ -n "${var2}" ]]; doob der aktuelle Wert der Variablen (aus der vorherigen Schleife oder so) wichtig sein sollte. Wenn er keine Rolle spielen sollte, sorgen Sie dafür, dass er keine Rolle spielt: Setzen Sie die Variable direkt vor zurück until.

Eine Alternative besteht darin, Ihren Code in Funktionen zu organisieren. In einer Funktion in Bash können Sie lokale Variablen definieren. Lokale var2Variablen haben nichts mit var2dem Hauptskript (falls vorhanden) oder mit var2einem anderen Aufruf dieser oder einer anderen Funktion zu tun. help localWeitere Einzelheiten finden Sie unter. Wenn Sie beispielsweise eine Funktion erstellen validate_invoice_numberund local var2darin definieren, können Sie sie until [[ -n "${var2}" ]]; doin der Funktion verwenden, ohne dass das Risiko besteht, dass eine andere (alte) Funktion var2dazwischenfunkt.


Beispiel

Der folgende Codeabschnitt ist ein fehlerhafter Versuch, zwei Zufallszahlen aus einem Bereich von 0bis zu erhalten 9999. In Bash $RANDOMwird zu einer zufälligen Ganzzahl aus einem Bereich von bis erweitert 0. 32767Wir werden Bash so lange nach Zufallszahlen abfragen, bis wir (zufällig) eine erhalten, die unseren Erwartungen entspricht. Dies ähnelt Ihrem Ansatz, bei dem Sie den Benutzer abfragen. Dies ist nicht die schnellste Methode, um eine zufällige Ganzzahl aus dem gewünschten Bereich zu erhalten, aber in diesem Fall ist sie auch nicht grundsätzlich fehlerhaft. Der Fehler liegt in der Wiederverwendung var2, wie in Ihrem Code. Diagnosemeldungen an stderr helfen Ihnen zu verstehen, was passiert.

#!/bin/bash

for i in 1 2; do
   echo "Loop $i starts. var2 is ${var2:-empty or unset}." >&2
   until [ "$var2" -lt 10000 ] 2>/dev/null; do
      echo "Trying new random number." >&2
      var2="$RANDOM"
   done
   echo "Expectation met. Printing the result." >&2
   echo "$var2"
   echo "Loop $i ends. var2 is ${var2:-empty or unset}." >&2
done

Führen Sie den Code aus und Sie werden sehen, dass die zweite Schleife überhaupt keine neue Zufallszahl erzeugt. Versuchen wir es jetzt mit unset:

#!/bin/bash

for i in 1 2; do
   echo "Loop $i starts. var2 is ${var2:-empty or unset}." >&2
   unset var2
   echo "Loop $i continues. var2 is ${var2:-empty or unset}." >&2
   until [ "$var2" -lt 10000 ] 2>/dev/null; do
      echo "Trying new random number." >&2
      var2="$RANDOM"
   done
   echo "Expectation met. Printing the result." >&2
   echo "$var2"
   echo "Loop $i ends. var2 is ${var2:-empty or unset}." >&2
done

local var2Ein anderer Ansatz besteht darin , in einer Funktion Folgendes zu verwenden :

#!/bin/bash

gimme_random () {
   local var2
   echo "Function starts. var2 inside is ${var2:-empty or unset}." >&2
   until [ "$var2" -lt 10000 ] 2>/dev/null; do
      echo "Trying new random number." >&2
      var2="$RANDOM"
   done
   echo "Expectation met. Printing the result." >&2
   echo "$var2"
   echo "Function ends. var2 inside is ${var2:-empty or unset}." >&2
}

for i in 1 2; do
   echo "Loop $i starts. var2 is ${var2:-empty or unset}." >&2
   gimme_random
   echo "Loop $i ends. var2 is ${var2:-empty or unset}." >&2
done

Dies funktioniert wie erwartet. Die Variable innerhalb der Funktion hat keine Verbindung zur Variable außerhalb der Funktion. Wenn die Funktion erneut ausgeführt wird, ist die Variable in der neuen Instanz lokal für die Instanz.

Versuchen Sie es ohne local var2und es wird sich wie der erste (fehlerhafte) Ausschnitt verhalten. In diesem Fall var2ist es außerhalb und innerhalb der Funktion (beide Instanzen) gleich var2.

Beachten Sie auch, dass, wenn Sie die Snippets ausführen, indem Sie sie einfach nacheinander in eine einzelne Shell einfügen, var2(sofern sie nicht lokal in der Funktion sind) von einem Snippet zum anderen übergegangen wird. Dies wird das Problem noch verschärfen.

verwandte Informationen