Dollarzeichen ($) vor Variablen in Shellskripts

Whiz-zarD schrieb:
Ich bin jetzt zwar ein bisschen raus aus der Shell-Entwicklung, aber müsste das nicht funktionieren:
Code:
#!/bin/bash
N=10
for i in {1..`echo $N`}
do
  echo "Hallo $i-mal!"
done

echo $N wird als Befehl ausgeführt und es steht dann dort 10 und {1..10} ist wiederrum eine reguläre Menge.
Nö, weil die Reihenfolge der Auswertung anders erfolgt als du es dir wünschst.

Bash nennt die Umwandlung von {1..10} in 1 2 3 4 5 6 7 8 9 10 "brace expansion". Dazu steht im bash-Manual insbesondere:
"Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces."

Dein {1..`echo $N`} ist für die bash gar keine brace expansion sondern ein Ausruck mit variable expansion (aus $N wird 10) und command substitution (aus `echo 10` wird 10) drin. Ergebnis ist die Zeichenkette {1..10}. Für brace expansion auf diese Zeichenkette ist es dann schon zu spät. Also wird diese Zeichkette {1..10} nun im ersten (und einzigen) Durchlauf der For-Schleife dem $i zugewiesen.

Willst du brace expansion auf einen variablen Audruck anwenden, musst du deine aus Variablen zusammengebastelte Zeichenkette {1..10} explizit ein 2. mal evaluieren:

Code:
#!/bin/bash
N=10
for i in `eval echo {1..$N}`
do
    echo "Hallo $i-mal!"
done
 
Zuletzt bearbeitet:
enteon schrieb:
dazwischen doch nicht, am ende! oder erscheint das shell-prompt unmittelbar nach der ausgabe von echo? wenn ich das \n kille ja (zugegeben das war stdout). die subshell zwackt es vielleicht wieder ab?
Häh? Wo hab ich das mit dem "dazwischen" denn behauptet? Wenn echo ein \n anhängen würde, müsste die Variable $gruss das \n noch enthalten, wenn ich es so definiere:
Code:
gruss=`echo Hallo`
Ergänzung ()

@mensch183: Vielen Dank, jetzt ist alles klar! Die Lösung von beig1 geht zwar auch, aber so wissen wir jetzt wenigstens, warum for i in {1..`echo $N`} nicht funktioniert.
 
Deine Variable gruss hat kein \n am Ende. Echo hängt ein \n dran, aber - wie von Enteon vermutet - es wird durch die subshell wieder entfernt.
Code:
 Command Substitution
    Command substitution allows the output of a command to replace the com‐
    mand name.  There are two forms:

            $(command)
    or
           `command`

    Bash performs the expansion by executing command and replacing the com‐
    mand substitution with the standard output of  the  command,  [b]with  any
    trailing newlines deleted[/b]. ...

Falls man das mal nicht will, weil es wichtig ist, ob das "command" Newline(s) am Ende hatte oder nicht, hängt man an den Output noch irgendwas hinten dran, was man danach wieder entfert. Statt

var=`befehl`
echo "$var"

schreibt man dazu:

var=`befehl; echo UNFUG`
var="${var%UNFUG}"
echo "$var"
 
Zuletzt bearbeitet:
Danke für die Erklärung, mein letzter Post war eigentlich nur eine Rechtfertigung, weil ich nicht verstanden habe und immer noch nicht verstehe, warum enteon meint, dass ich so furchtbar falsch gelegen habe.
 

Ähnliche Themen

Antworten
2
Aufrufe
1.191
T
Antworten
3
Aufrufe
5.563
Tallatronic
T
Zurück
Oben