Weisen Sie einfach alle Variablen zu und schreiben Sie die Ausgabe gleichzeitig.
f() { c= ; echo "${c:=$(date): $((a=3)) $((b=4))}" ; }
Wenn Sie dies tun:
f ; echo "$a $b $c"
Ihre Ausgabe ist:
Tue Jul 1 04:58:17 PDT 2014: 3 4
3 4 Tue Jul 1 04:58:17 PDT 2014: 3 4
Beachten Sie, dass dies vollständig tragbarer POSIX-Code ist. Ich habe anfangs c=
die ''
Nullzeichenfolge festgelegt, weil die Parametererweiterung die gleichzeitige Variablenzuweisung + Auswertung entweder nur auf numerische (wie $((var=num))
) oder von null oder nicht vorhandenen Werten beschränkt - oder mit anderen Worten, Sie können eine Variable nicht gleichzeitig auf eine beliebige Zeichenfolge setzen und auswerten wenn dieser Variablen bereits ein Wert zugewiesen ist. Also stelle ich einfach sicher, dass es leer ist, bevor ich es versuche. Wenn ich c
vor dem Versuch, es zuzuweisen, nicht leer wäre, würde die Erweiterung nur den alten Wert zurückgeben.
Nur um zu demonstrieren:
sh -c '
c=oldval a=1
echo ${c:=newval} $((a=a+a))
'
###OUTPUT###
oldval 2
newval
wird nicht$c
inline zugewiesen, da oldval
in erweitert wird ${word}
, während die inline- $((
arithmetische =
Zuweisung ))
immer erfolgt. Aber wenn $c
nein hat oldval
und leer oder nicht gesetzt ist ...
sh -c '
c=oldval a=1
echo ${c:=newval} $((a=a+a))
c= a=$((a+a))
echo ${c:=newval} $((a=a+a))
'
###OUTPUT###
oldval 2
newval 8
... wird dann newval
sofort zugeordnet und erweitert $c
.
Alle anderen Möglichkeiten, dies zu tun, beinhalten irgendeine Form der sekundären Bewertung. Nehmen wir zum Beispiel an, ich wollte die Ausgabe f()
einer Variablen zuweisen, die name
an einem Punkt und var
an einem anderen benannt ist. Wie derzeit geschrieben, funktioniert dies nicht, ohne die Variable im Bereich des Aufrufers festzulegen. Ein anderer Weg könnte jedoch so aussehen:
f(){ fout_name= fout= set -- "${1##[0-9]*}" "${1%%*[![:alnum:]]*}"
(: ${2:?invalid or unspecified param - name set to fout}) || set --
export "${fout_name:=${1:-fout}}=${fout:=$(date): $((a=${a:-50}+1)) $((b=${b:-100}-4))}"
printf %s\\n "$fout"
}
f &&
printf %s\\n \
"$fout_name" \
"$fout" \
"$a" "$b"
Ich habe unten ein besser formatiertes Beispiel bereitgestellt, aber wie oben genannt lautet die Ausgabe:
sh: line 2: 2: invalid or unspecified param - name set to fout
Wed Jul 2 02:27:07 PDT 2014: 51 96
fout
Wed Jul 2 02:27:07 PDT 2014: 51 96
51
96
Oder mit anderen $ENV
oder Argumenten:
b=9 f myvar &&
printf %s\\n \
"$fout_name" \
"$fout" \
"$myvar" \
"$a" "$b"
###OUTPUT###
Tue Jul 1 19:56:42 PDT 2014: 52 5
myvar
Tue Jul 1 19:56:42 PDT 2014: 52 5
Tue Jul 1 19:56:42 PDT 2014: 52 5
52
5
Bei der zweimaligen Auswertung ist es wahrscheinlich am schwierigsten, sicherzustellen, dass Variablen keine Anführungszeichen brechen und zufälligen Code ausführen. Je öfter eine Variable ausgewertet wird, desto schwieriger wird es. Die Parametererweiterung hilft hier sehr, und die Verwendung export
im Gegensatz zu eval
ist weitaus sicherer.
Im obigen Beispiel wird f()
zuerst $fout
die ''
Nullzeichenfolge zugewiesen und dann Positionsparameter festgelegt, um auf gültige Variablennamen zu testen. Wenn beide Tests nicht bestanden werden, wird eine Nachricht ausgegeben stderr
und der Standardwert von fout
zugewiesen $fout_name
. Unabhängig von den Tests wird jedoch $fout_name
immer entweder fout
oder dem von Ihnen $fout
angegebenen Namen zugewiesen , und optional wird Ihrem angegebenen Namen immer der Ausgabewert der Funktion zugewiesen. Um dies zu demonstrieren, habe ich diese kleine for
Schleife geschrieben:
for v in var '' "wr;\' ong"
do sleep 10 &&
a=${a:+$((a*2))} f "$v" || break
echo "${v:-'' #null}"
printf '#\t"$%s" = '"'%s'\n" \
a "$a" b "$b" \
fout_name "$fout_name" \
fout "$fout" \
'(eval '\''echo "$'\''"$fout_name"\")' \
"$(eval 'echo "$'"$fout_name"\")"
done
Es spielt einige mit Variablennamen und Parametererweiterungen herum. Wenn Sie eine Frage haben, fragen Sie einfach. Das läuft nur die wenigen Zeilen in der hier bereits dargestellten Funktion. Zumindest ist zu erwähnen, dass sich die Variablen $a
und $b
unterschiedlich verhalten, je nachdem, ob sie beim Aufruf definiert oder bereits festgelegt wurden. Trotzdem for
macht der fast nichts anderes, als den Datensatz zu formatieren und bereitzustellen von f()
. Guck mal:
###OUTPUT###
Wed Jul 2 02:50:17 PDT 2014: 51 96
var
# "$a" = '51'
# "$b" = '96'
# "$fout_name" = 'var'
# "$fout" = 'Wed Jul 2 02:50:17 PDT 2014: 51 96'
# "$(eval 'echo "$'"$fout_name"\")" = 'Wed Jul 2 02:50:17 PDT 2014: 51 96'
sh: line 2: 2: invalid or unspecified param - name set to fout
Wed Jul 2 02:50:27 PDT 2014: 103 92
'' #null
# "$a" = '103'
# "$b" = '92'
# "$fout_name" = 'fout'
# "$fout" = 'Wed Jul 2 02:50:27 PDT 2014: 103 92'
# "$(eval 'echo "$'"$fout_name"\")" = 'Wed Jul 2 02:50:27 PDT 2014: 103 92'
sh: line 2: 2: invalid or unspecified param - name set to fout
Wed Jul 2 02:50:37 PDT 2014: 207 88
wr;\' ong
# "$a" = '207'
# "$b" = '88'
# "$fout_name" = 'fout'
# "$fout" = 'Wed Jul 2 02:50:37 PDT 2014: 207 88'
# "$(eval 'echo "$'"$fout_name"\")" = 'Wed Jul 2 02:50:37 PDT 2014: 207 88'
$a
und$b
sind lokale Variablen in Ihrerf
Funktion. Sie könntenexport
sie, aber das scheint lückenhaft.