[gelöst] Array-Zuweisungsproblem im Bash-Script

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
worker777
Beiträge: 103
Registriert: 14.04.2015 07:59:26

[gelöst] Array-Zuweisungsproblem im Bash-Script

Beitrag von worker777 » 14.11.2020 17:23:37

Hallo Community,

ich habe hier ein seltsames Problem beim Zuweisen von Arraywerten.
Und zwar geht es um diesen Code:

Code: Alles auswählen

# Alle HDDs auflisten:
#--------------------------

HDD_FOUND_RESULT=''
HDDS=''
HDD_FOUND_RESULT=$(fdisk -l | grep 'Disk /dev/sd' | awk {'print $1" "$2" "$3" "$4'})
HDDS=$(echo "$HDD_FOUND_RESULT" | sed 's/,/ /g' | awk '{print $1" "$2" "$3" "$4}')

#HDDS_ARRAY=()
declare -a HDDS_ARRAY

LINE_COUNTER=0

# Arrays-Zuweisung:
# ----------------------
echo "$HDDS" | while read HDD_LINE
do
    HDDS_ARRAY[$LINE_COUNTER]="$HDD_LINE"
    echo "HDDS_ARRAY[$LINE_COUNTER]: ${HDDS_ARRAY[$LINE_COUNTER]} (${#HDDS_ARRAY[$LINE_COUNTER]})"

    LINE_COUNTER=$(($LINE_COUNTER+1))
done

LINE_COUNTER=0

# Arrays wieder auslesen:
# -----------------------------
while [ $LINE_COUNTER -lt 3 ]
do
    echo "HDDS_ARRAY[$LINE_COUNTER]: ${HDDS_ARRAY[$LINE_COUNTER]} (${#HDDS_ARRAY[$LINE_COUNTER]})"

    LINE_COUNTER=$(($LINE_COUNTER+1))
done
Zum Problem:
In der ersten while-do - Anweisung ("Arrays-Zuweisung") werden die Werte von HDD_LINE entsprechend den Array-Feldern zugewiesen. Das kann man anhand der sofortigen echo-Ausgabe sehen/überprüfen.
Jedoch in der zweiten while-do - Anweisung ("Arrays wieder auslesen") sind die Array-Felder leer.
Was mache ich da falsch, bzw. wie kommt das zustande?
Zuletzt geändert von worker777 am 14.11.2020 18:13:43, insgesamt 2-mal geändert.

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Array-Zuweisungsproblem im Bash-Script

Beitrag von JTH » 14.11.2020 18:07:02

Das ist eine übliche Falle mit Schleifen, wenn du einen Input reinpipest:

Code: Alles auswählen

echo "$HDDS" | while read HDD_LINE
do
    [...]
done
Jedes Kommando in einer Pipeline

Code: Alles auswählen

echo "a b c" | ...
läuft in einer eigenen Subshell, damit auch deine gesamte Schleife. Variablen, die in einer Subshell, also einer separaten Umgebung mit eigenen Variablen, gesetzt werden, sind aber außerhalb dieser nicht sichtbar. Deine Zuweisungen zum Array funktionieren innerhalb der Schleife, kommen in dem umgebenden Skript aber nicht an.

Zwei mögliche Lösungen dafür:
Hier am passendsten, da du deine Eingabe schon als Variable hast: Ein Here-String als Eingabe für die Schleife:

Code: Alles auswählen

while read HDD_LINE
do
    [...]
done <<<"$HDDS"

Oder, für andere Fälle, in denen du unbedingt die Ausgabe eines Kommandos in die Schleife bekommen musst, hier mehr nur als Beispiel: Eine Process-Substitution mit Inputredirection:

Code: Alles auswählen

while read HDD_LINE
do
    [...]
done < <(echo "$HDDS")

Als Hintergrund: I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?
Manchmal bekannt als Just (another) Terminal Hacker.

worker777
Beiträge: 103
Registriert: 14.04.2015 07:59:26

Re: Array-Zuweisungsproblem im Bash-Script

Beitrag von worker777 » 14.11.2020 18:09:33

Jedes Kommando in einer Pipeline läuft in einer eigenen Subshell
Achso ....
Dieses "Detail" wusste ich nicht.

Vielen Dank!

Antworten