
Problem mit Variabler
-
-
Dafür gibt es Arrays (deren Index fängt aber wie bei von C inspirierten Sprachen üblich bei 0 an): https://www.gnu.org/software/bash/…ode/Arrays.html
-
Hi seahawk1986,
Danke.
Dann mach ich aber irgendwas anderes falsch denn ich habs auch mit nem array probiert, mein Beispiel in Post 1 war auch nicht grade optimal gewählt.
Also ich hatte mit array das probiert;
Bash
Display More#!/bin/bash parts=4 sizes=(size_1 size_2 size_3 size_4 size_5) z=1 for i in ${sizes[@]:0:$parts} ; do while true; do read -n 7 -p "please select the size in KiB for size_$z ?" size_$z echo "" case ${sizes[$z]} in [0-9][0-9][0-9][0-9][0-9][0-9][0-9]* ) echo ${sizes[$z]} && echo "${sizes[$z]}" && break;; * ) echo -e "\n${yellow}please answer with numbers from 0 to 9.${green}\n";; esac done z=$((z+1)) done exit
Ich will halt am Ende da in dem Fall parts=4 vier Variablen haben in etwa so;
size_1=5555555
size_2=4444444
size_3=3333333
size_4=2222222
so als ob diese Variablen fix im Script eingetragen wurden also das dann z.b: ein echo $size_1 als Ergebnis 5555555 ausgibt.
Das gelingt mir nicht (read akzeptiert da einfach kein Dollarzeichen also ne bereits gefüllte Variable), ich könnte da ja auch REPLY nehmen stattdessen
aber das hab ich alles schon probiert und hat mich auch nicht weitergebracht (hab wohl irgendwo nen Denkfehler).
Klar es gibt auch andere Lösungen ich will das aber so kurz wie möglich halten, das Script oben gibt dann das aus:
Codebash /usr/script/_testing.sh please select the size in KiB for size_1 ?5555555 please answer with numbers from 0 to 9. please select the size in KiB for size_1 ?
das geht leider völlig daneben wie man sieht.
Das mit dem bei 0 anfangen beim array dagegen kann man eh was tun, aber das ist erstmal nur sekundär für mich.
Ich hatte es auch schon soweit das size_1 size_2 usw.. korrekt abgefragt wurden aber die Variablen waren danach dennoch falsch gefüllt.
Gruss
Bert
-
mappe_$c=$var
-bash: mappe_1=text: command not foundEvtl. geht das mit Referenzen declare -n variable das macht IMHO das ganze aber unnötig kompliziert
Ich würde das auch mit einem Array machen, dabei ist parts auch variabel:
Bash
Display More#!/bin/bash read -p "parts ? " parts for i in $(seq 1 $parts); do while true; do read -n 7 -p "please enter the size in KiB for size[$i]: " value case $value in [0-9][0-9][0-9][0-9][0-9][0-9][0-9] ) sizes[$i]=$value echo -e "\n sizes[$i] = ${sizes[$i]}" break ;; * ) echo -e "\n${yellow}please answer with numbers from 0 to 9.${green}\n";; esac done done echo "sizes: ${sizes[@]}" exit
-
Hi FireFly,
Danke, werd das gleich testen.
Gruss
Bert
-
Hi Jungs,
Das sind alles schöne Ansätze, aber ich steh dennoch immer wieder vor dem selben Problem.
Ich versuch das jetzt mal besser bzw. genauer zu erklären was ich eigentlich will, es ist wie folgt;
Ich möchte in ner Schleife interaktiv die size abfragen wobei die size is nix anderes als ne Grösse die man eingibt in Form von Zahlen
und zwar soll das die Grösse in KiB darstellen.
wie oft die size abgfragt wird das wiederum hängt von der Variablen parts ab, also z.b: wenn
parts=4
dann wird die size 4x abgefragt, bis hierher keinerlei Problem
doch möchte ich mittels nem Zähler der mit (z=1) anfängt pro Schleifendurchlauf an die variable size ne Nummer anhängen.
also wenn nun size gefüllt ist mit z.b: 5555555 so das echo "$size" eben 5555555 ausgibt möchte ich diese Variable (jetzt mal grob gesagt)
quasi umbenennen so das size nachher size_1 ist und echo $size_1 die 5555555 ausgibt.
Beim nächsten Schleifendurchlauf wird dann der Zähler erhöht mit z=$((z+1)) und dann sollte aus size mit was immer diese Variable nun gefüllt wurde
size_2 werden usw...
Hab da ziemlich einfach gedacht und dachte das kann doch in der bash nie ein Problem sein und es würde das folgende genügen,
also wenn da nun wie von FireFly statt der REPLY variablen value verwendet wird:
dann dachte ich, ok ich mach mal:
doch das klappt ja nicht.
Dank FireFly weiss ich nun das sowas stattdessen klappt:
doch ist das ja dennoch keine Variable die ich so weiter verwenden kann, denn ein echo $size[$z] gibt ja jetzt lediglich den Zähler aus
also die variable z und das in eckigen Klammern.
Vereinfacht gezeigt sieht man das Problem wie folgt am Besten denke ich:
klappt nicht:
hingegen ohne variable für den Zähler (z) klappt das problemlos:
Ich hab ne Lösung aber die benötigt keinerlei array, und braucht aber zwei while Schleifen sowie ein case und innerhalb vom case ein paar if elif Abfragen also so:
Das klappt dann natürlich, allerdings hatte ich gehofft das kürzer hinzubekommem, ich bin nicht sicher ob sowas mit nem array und ohne den ifs
hinzubekommen ist, doch wenn das ginge würd ich gerne wissen wie ?
Hier mal meine derzeitige Lösung:
wobei die Variable parts und DEV usw.. frage ich eh auch bereits an anderer Stelle interaktiv ab (das hier ist halt nur der relevante Codeschnipsel
und damit der funktioniert (falls den jemand testen will - Script tut eh nix wirkliches bzw. gefährliches) hab ich diese Variablen derweil so darin vorgegeben.
Display Spoiler
Bash
Display More#!/bin/bash yellow="\033[33m" green="\033[32m" blue="\e[1m\e[34m" red="\e[1m\e[31m" cyan="\033[36m" to_default="\033[0m" DEV=sdb E_SIZE="$(df -k | grep /dev/$DEV | awk '{print $2}')" KiB=1048576 E_SIZE_GiB=$(($E_SIZE/$KiB)) parts=4 echo -e "$green" z=1 while [ $z -le $parts ] ; do while true; do read -p "please select the size in GiB for size_$z ?" size_gb echo "" case "$size_gb" in [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9]) echo -e "\nchosen was ${blue}$size_gb${green} for ${blue}size_$z${green}\n" if [ "$z" = "1" ] ; then size_1=$size_gb && echo -e "\n${blue}size_${z}_GiB${green} = ${blue}$size_gb GiB\n${green}" size_1=$(($size_1*$KiB)) && SUM=$size_gb elif [ "$z" = "2" ] ; then size_2=$size_gb && echo -e "\n${blue}size_${z}_GiB${green} = ${blue}$size_gb GiB\n${green}" size_2=$(($size_2*$KiB)) && SUM=$(($SUM+$size_gb)) elif [ "$z" = "3" ] ; then size_3=$size_gb && echo -e "\n${blue}size_${z}_GiB${green} = ${blue}$size_gb GiB\n${green}" size_3=$(($size_3*$KiB)) && SUM=$(($SUM+$size_gb)) elif [ "$z" = "4" ] ; then size_4=$size_gb && echo -e "\n${blue}size_${z}_GiB${green} = ${blue}$size_gb GiB\n${green}" size_4=$(($size_4*$KiB)) && SUM=$(($SUM+$size_gb)) elif [ "$z" = "5" ] ; then size_5=$size_gb && echo -e "\n${blue}size_${z}_GiB${green} = ${blue}$size_gb GiB\n${green}" size_5=$(($size_5*$KiB)) && SUM=$(($SUM+$size_gb)) fi break ;; * ) echo -e "\n${yellow}please answer with numbers from 0 to 9 from single-digit to four-digit.${green}\n";; esac done z=$((z+1)) done TOTAL_SIZE=$((SUM*$KiB)) echo -e "\nESTIMATED_SIZE_GiB FOR ${blue}$DEV${green} = ${blue}$E_SIZE_GiB GiB${green}" echo -e "ESTIMATED_SIZE FOR ${blue}$DEV${green} = ${blue}$E_SIZE KiB${green}" echo -e "\nTOTAL_SIZE_GiB = ${blue}$SUM GiB${green}" echo -e "TOTAL_SIZE = ${blue}$TOTAL_SIZE KiB${green}" ## check if the selected partition size(s) are not bigger as the device size, if so then the script ends. if [ "$E_SIZE" -lt "$TOTAL_SIZE" ] ; then echo -e "\n${red}... ABORT ...\nthe total size of the partitons is larger\nthan the available space on device ${blue}$DEV.${red}" echo -e "start $0 again, and\nmake your selections new.\n\n" && exit 1 fi echo -e "\nsize_1 = $size_1" echo "size_2 = $size_2" echo "size_3 = $size_3" echo "size_4 = $size_4" echo -e "size_5 = $size_5\n" exit
und so sieht das bei der Ausführung aus:
Gruss
Bert
-
-
Ach ja, und was genau bei den Arrays nicht funktioniert bei Dir ist mir noch nicht so ganz klar...
doch ist das ja dennoch keine Variable die ich so weiter verwenden kann, denn ein echo $size[$z] gibt ja jetzt lediglich den Zähler aus
also die variable z und das in eckigen Klammern.
Du wolltest eventuell
nehmen?
rfu
-
doch ist das ja dennoch keine Variable die ich so weiter verwenden kann, denn ein echo $size[$z] gibt ja jetzt lediglich den Zähler aus
Der Zugriff auf die Werte eines Arrays funktioniert anders - wenn du den Wert aus dem Array size am Index z haben willst:
Und wenn du eh nichts anderes machst als über die Elemente im Array zu laufen, dann reicht so eine for-Schleife:
Falls du einen laufenden Index benötigst, ist es üblich über die Indices zu laufen statt extern zu zählen:
-
Bert : wenn es kein Array sein soll, kann man mit "eval" Variable auch dynamisch erzeugen.
Hier dein vereinfachtes Script aus dem Post #3:
Code
Display More#! /bin/bash #set -x parts=4 for ((i=1; i<=$parts; i++)) ; do while true; do read -n 7 -p "please select the size in KiB for size_$i ? " n case $n} in [0-9]*) eval "size_$i=$n" && break;; * ) echo -e "\n${yellow}please answer with numbers from 0 to 9.${green}\n";; esac done done for ((i=1; i<=$parts; i++)) ; do echo "size_$i = $((size_$i))" done exit
Das Ergebnis:
Codegentoo64 ~/bin # ./_testing.sh please select the size in KiB for size_1 ? 123 please select the size in KiB for size_2 ? 456 please select the size in KiB for size_3 ? 789 please select the size in KiB for size_4 ? 100 size_1 = 123 size_2 = 456 size_3 = 789 size_4 = 100
LG Helmut
-
Hi,
Ihr seid super
Das haut soweit alles hin nun, das von rfu mit dem export (an das hab ich nicht mal gedacht), sieht jetzt insgesamt wie folgend aus
wobei ich das mit dem Code von FireFly getestet habe, also so:
Display Spoiler
Bash
Display More#!/bin/bash yellow="\033[33m" green="\033[32m" blue="\e[1m\e[34m" red="\e[1m\e[31m" cyan="\033[36m" to_default="\033[0m" parts=5 z=1 echo -e "$green" while [ $z -le $parts ] ; do while true; do read -p "please enter the size in GiB for size_$z: " value case $value in [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9]) size_[$z]=$value export size_${z}=$value echo -e "\n${blue}size_$z${green} = ${blue}$value${green}\n" break ;; * ) echo -e "\n${yellow}please answer with numbers from 0 to 9 from single-digit to four-digit.${green}\n";; esac done z=$((z+1)) done echo -e "\ncomplete sizes: ${blue}${size_[@]}\n" echo -e "$to_default" echo "size_1 = $size_1" echo "size_2 = $size_2" echo "size_3 = $size_3" echo "size_4 = $size_4" echo "size_5 = $size_5" exit
Die Ausgabe dazu sieht dann so aus:
Code
Display Moresh /usr/script/_testing.sh please enter the size in GiB for size_1: 1 size_1 = 1 please enter the size in GiB for size_2: 2 size_2 = 2 please enter the size in GiB for size_3: 3 size_3 = 3 please enter the size in GiB for size_4: 4 size_4 = 4 please enter the size in GiB for size_5: 5 size_5 = 5 complete sizes: 1 2 3 4 5 size_1 = 1 size_2 = 2 size_3 = 3 size_4 = 4 size_5 = 5
Auch das von HelmutB † mit eval haut super hin, sieht so aus:
Display Spoiler
Bash
Display More#!/bin/bash yellow="\033[33m" green="\033[32m" blue="\e[1m\e[34m" red="\e[1m\e[31m" cyan="\033[36m" to_default="\033[0m" #set -x parts=4 echo -e "$green" for ((i=1; i<=$parts; i++)) ; do while true; do read -p "please enter the size in GiB for size_$i: " size_gb case $size_gb in [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9]) eval "size_$i=$size_gb" echo -e "\n${blue}size_$i${green} = ${blue}$((size_$i))${green}\n" && break;; * ) echo -e "\n${yellow}please answer with numbers from 0 to 9 from single-digit to four-digit.${green}\n";; esac done done echo -e "$to_default" echo "size_1 = $size_1" echo "size_2 = $size_2" echo "size_3 = $size_3" echo "size_4 = $size_4" echo "size_5 = $size_5" exit
Die Ausgabe dazu sieht so aus:
Code
Display Moresh /usr/script/_testing.sh please enter the size in GiB for size_1: 15 size_1 = 15 please enter the size in GiB for size_2: 2 size_2 = 2 please enter the size in GiB for size_3: 333 size_3 = 333 please enter the size in GiB for size_4: 4444 size_4 = 4444 size_1 = 15 size_2 = 2 size_3 = 333 size_4 = 4444 size_5 =
Also alles super, nun muss ich noch gucken mit nem array wie von seahawk1986 vorgeschlagen, aber sind jetzt schon schöne kurze Lösungen.
Hab ja schon öfters mal arrays in Scripts eingebaut aber noch nicht für so nen Fall (steh da immer noch am Schlauch) aber das wird schon noch.
Vielen Dank an alle Beteiligten hier
kann man nun eigentlich als gelöst betrachten den Thread.
Gruss
Bert
Participate now!
Don’t have an account yet? Register yourself now and be a part of our community!