king_siggi
Anmeldungsdatum: 24. November 2015
Beiträge: Zähle...
|
Guten Tag, ich versuche derzeit in einem Skript eine Variable "Variable/ Dynamisch" aufzurufen. Ich versuche das mal zu veranschaulichen. | zaehler=1
inhouse_name_count="$(echo "SELECT count(*) FROM inhouse" | mysql --skip-column-names -u **** -p***** ****)";
inhouse_name_count1=$(expr $inhouse_name_count + 1)
while [ $zaehler -lt $inhouse_name_count1 ]
do
eval inhouse_name${zaehler}="$(echo "select server_name from inhouse WHERE id = $zaehler" | mysql --skip-column-names -u **** -p***** ****)";
zaehler=$(($zaehler+1))
done
|
Das Ergebnis hiervon ist das ich bspw. die Variable $inhouse_name13 aufrufen kann und dann den entsprechen wert aus der Datenbank erhalte. Nun zu dem Zweiten Teil: | zaehler=1
dir_count="$(echo "SELECT count(*) FROM inhouse" | mysql --skip-column-names -u **** -p***** ****)";
dir_count1=$(expr $dir_count + 1)
while [ $zaehler -lt $dir_count1 ]
do
echo "inhouse_name"$zaehler
zaehler=$(($zaehler+1))
done
|
Das Ergebnis hiervon soll! sein das ich nun nacheinander jeden einzelnen Wert ausgegeben bekomme. Also den wert der hinter $inhouse_name1; $inhouse_name2 und so weiter steht.
Logischer weise bekomme ich mit dem Obigen Code als ausgabe nur "inhouse_name1" als string geliefert, ich jedoch brauche den Wert der hinter der Variable "inhouse_name1" steht. Ich weiß das ganze ist etwas schwer zu Erklären/ Verstehen, aber ich hoffe das Ihr damit wisst was ich meine und mir vielleicht einen Rat geben könnt wie man dies Lösen kann. Danke im Voraus
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Hi Majestät, erstmal herzlich willkommen hier auf dem Forum ! Das was Du da machen willst, ist eigentlich ein ganz typischer Fall für Arrays. Aber gut, wenn Du es unbedingt willst, dann kannst Du es mit eval hintricksen: track@track:~$ var1=A
track@track:~$ var2=B
track@track:~$ var3=C
track@track:~$ for i in 1 2 3; do x=var$i; echo $x; eval echo \$$x ; done
var1
A
var2
B
var3
C Allerdings ist eval immer so eine Sache, weil es ein Sicherheitsleck darstellt. (→ Daten werden plötzlich ausführbar !!) LG, track
|
senden9
Anmeldungsdatum: 8. Februar 2010
Beiträge: 965
Wohnort: Österreich
|
Hallo, Ich glaube du versuchst hier ein Array nach zubauen.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Mit mysql kenne ich mich nicht aus, aber 2 Dinge lassen sich wohl auch so sagen: a) | dir_count1=$(expr $dir_count + 1)
while [ $zaehler -lt $dir_count1 ]
do
echo "inhouse_name"$zaehler
zaehler=$(($zaehler+1))
|
Bei dir_count1 und zaehler benutzt Du 2 unterschiedliche Formen arithmetischer Aufrufe. Der zweite ist billiger und der empfohlene. Allerdings ist das Dollarsymbol vor dem Namen in arithmetischen Ausdrücken überflüssig: | zaehler=$((zaehler+1))
# geht auch und noch kuerzer
((zaehler+=1))
|
Problem 2, indizierte Variablen.
Das geht am besten mit Arrays. | declare -a inhouse_name
inhouse_name=($(seq 1 $dir_count1))
inhouse_name[4]=9
inhouse_name[$foo]=$bar
echo ${inhouse_name[@]}
|
|
TausB
Anmeldungsdatum: 26. November 2009
Beiträge: 1563
Wohnort: Terra incognita
|
track schrieb: Allerdings ist eval immer so eine Sache, weil es ein Sicherheitsleck darstellt. (→ Daten werden plötzlich ausführbar !!)
Weil das so ist, man aber trotzdem evtl. kein array nutzen möchte, geht es auch so:
| var1=A
var2=B
var3=C
for i in 1 2 3 ; do
var="var$i"
echo ${!var}
done
|
Diese Variante wird gern übersehen. 😉
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Die Substring Expansion dafür zu nehmen ist hübsch ! ... ich hatte sie tatsächlich nicht auf dem Schirm, wahrscheinlich weil die mit ihrem exotischen Flair immer unter "ferner liefen" verschwindet. Ist aber auf jeden Fall die Lösung der Wahl ! LG, und besonderen Dank für den Tip, track
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Die habe ich auch kürzlich erst gesehen, und mir nicht gemerkt wie es geht. Ich weiß auch nicht wie ich mir merken soll, wie ich es in der Manpage wiederfinde. Substring Expansion, ja, kann ich mir nicht merken. ☺
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12823
|
track schrieb: Die Substring Expansion dafür zu nehmen ist hübsch ! ... ich hatte sie tatsächlich nicht auf dem Schirm, wahrscheinlich weil die mit ihrem exotischen Flair immer unter "ferner liefen" verschwindet.
Geht mir auch so. Ich skripte soweit möglich auch immer mit der sh :
Ist aber auf jeden Fall die Lösung der Wahl !
Soweit ich das sehe, gibt es die in der sh nicht und die ist auch nicht POSIX-kompatibel. Wenn man also sowieso schon eine bash , zsh o.ä. benötigt, erscheint mir ein Array das deutlich bessere Mittel der Wahl. Es gibt noch ein paar grundsätzliche Anmerkungen zur Verfahrensweise:
Es ist sehr ineffizient, für jede Zeile einen SELECT abzusetzen. Das Verfahren erfasst nur wirklich alle Datensätze, wenn es keine Lücken bei der Spalte "id" gibt. Die Ausgabe von echo nach mysql zu füttern ist auch überflüssig, da man über die Option "-e" ein SQL-Statement absetzen kann (sagt zumindest die Manpage).
Man müsste wissen, was mit den Daten weiters passieren soll, um eine sinnvolle Alternative anzubieten. Wenn man diese Variablen so definieren will, könnte dies gehen: | eval "$(mysql --skip-column-names -u **** -p***** **** -e "select concat('inhouse_name', id, '=', server_name) from inhouse")"
|
|
king_siggi
(Themenstarter)
Anmeldungsdatum: 24. November 2015
Beiträge: 2
|
Guten Tag, so nach dem ich mir noch einige Zeit mit allen tipps den Kopf darüber zerbrochen habe bin ich nun auf die Lösung gekommen.
Erstmal zum Ergebnis: | zaehler=1
dir_count="$(echo "SELECT count(*) FROM inhouse" | mysql --skip-column-names -u **** -p***** ****)";
dir_count1=$(expr $dir_count + 1)
while [ $zaehler -lt $dir_count1 ]
do
inhouse_name="inhouse_name"$zaehler
echo ${!inhouse_name}
((zaehler+=1))
done
|
Die Idee mit einem Array zu arbeiten fand ich sehr gut, doch ich muss zugeben das ich bisher nie damit gearbeitet hatte und mich damit erstmal kurz im allgemeinen beschäftigt habe.
Nun bin ich mit dem Array aber auf das selbe ergebnis gekommen,- immer nur zb. "$inhouse_name12" aber nicht die auflösung von "$inhouse_name12". Um noch einmal den Punkt anzusprechen was mit den Daten passieren soll, folgendes: aufzurufen. In dem Code den ich hier gepostet habe wäre die nachfolgende Aktion diese:
| mkdir -p /hier/ist/der/pfad/${!inhouse_name}
|
Es soll also in diesem beispiel jeder Wert genommen werden um einen Ordner mit dem entsprechenden Namen anzulegen.
Ich hoffe ihr konntet mir hier folgen und ich hab es ausführlich genug beschrieben. Vielen Dank für eure Unterstützung
LG Siggi ☺
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Wenn Du bisher noch nie mit Arrays was gemacht hast, mag es etwas Eingewöhnung brauchen, ist aber im Grunde ganz simpel: Du hast eine Variable mit beliebig vielen Feldern, die Du über den [Index] ansprechen kannst: track@track:~$ x=( A B C D E ) # die 5 Zellen werden zusammen am Stück gefüllt
track@track:~$ for i in {0..4} ; do echo "$i: ${x[i]}"; done # und in einer Schleife Index und Inhalt einzeln ausgegeben:
0: A
1: B
2: C
3: D
4: E Zum genauen Verständnis lies bitte oben meinen Link dazu nochmal nach ! LG, track
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12823
|
king_siggi schrieb:
so nach dem ich mir noch einige Zeit mit allen tipps den Kopf darüber zerbrochen habe bin ich nun auf die Lösung gekommen.
Erstmal zum Ergebnis: [...]
Das ist aber immer noch eine Schleife. Das ist ineffizient und unnötig.
In dem Code den ich hier gepostet habe wäre die nachfolgende Aktion diese:
| mkdir -p /hier/ist/der/pfad/${!inhouse_name}
|
Es soll also in diesem beispiel jeder Wert genommen werden um einen Ordner mit dem entsprechenden Namen anzulegen.
Dann kannst Du Dein ganzes Skript in einen Einzeiler verwandeln: | mysql -B --skip-column-names -u **** -p***** **** -e "select concat('mkdir /hier/ist/der/pfad/', server_name) from inhouse" | sh
|
oder, etwas robuster | mysql -B --skip-column-names -u **** -p***** **** \
-e "select concat('mkdir ''/hier/ist/der/pfad/', server_name, ''';') from inhouse where server_name not is null" | sh
|
Ich hoffe ihr konntet mir hier folgen und ich hab es ausführlich genug beschrieben.
Ja, ich denke schon.
|