Basta assegnare tutte le variabili e scrivere l'output contemporaneamente.
f() { c= ; echo "${c:=$(date): $((a=3)) $((b=4))}" ; }
Ora se lo fai:
f ; echo "$a $b $c"
Il tuo output è:
Tue Jul 1 04:58:17 PDT 2014: 3 4
3 4 Tue Jul 1 04:58:17 PDT 2014: 3 4
Si noti che questo è un codice portatile completamente POSIX. Inizialmente ho impostato c=la ''stringa nulla perché l'espansione del parametro limita l'assegnazione variabile simultanea + valutazione a solo valori numerici (come $((var=num))) o da valori null o inesistenti - o, in altre parole, non è possibile impostare e valutare contemporaneamente una variabile in una stringa arbitraria se a quella variabile è già stato assegnato un valore. Quindi mi assicuro che sia vuoto prima di provare. Se non avessi svuotato cprima di provare ad assegnarlo, l'espansione restituirebbe solo il vecchio valore.
Giusto per dimostrare:
sh -c '
c=oldval a=1
echo ${c:=newval} $((a=a+a))
'
###OUTPUT###
oldval 2
newvalnon è assegnato a $cinline perché oldvalè espanso in ${word}, mentre si verifica sempre l' assegnazione $((aritmetica inline . Ma se ha no ed è vuoto o non impostato ...=))$c oldval
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
... quindi newvalviene subito assegnato e ampliato in $c.
Tutti gli altri modi per farlo comportano una qualche forma di valutazione secondaria. Ad esempio, supponiamo di voler assegnare l'output di f()a una variabile denominata namein un punto e varin un altro. Come attualmente scritto, questo non funzionerà senza impostare il var nell'ambito del chiamante. Un modo diverso potrebbe apparire così:
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"
Ho fornito un esempio meglio formattato di seguito, ma, chiamato come sopra, l'output è:
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
O con differenti $ENVo argomenti:
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
Probabilmente la cosa più difficile da ottenere quando si tratta di valutare due volte è assicurarsi che le variabili non rompano le virgolette ed eseguano codice casuale. Più volte viene valutata una variabile, più diventa difficile. L'espansione dei parametri aiuta molto qui, e l'utilizzo exportal contrario evalè molto più sicuro.
Nell'esempio sopra f()assegna prima $foutla ''stringa nulla e quindi imposta i parametri posizionali per verificare i nomi di variabili validi. Se entrambi i test non vengono superati, viene emesso un messaggio stderre foutviene assegnato il valore predefinito di $fout_name. Indipendentemente dai test, tuttavia, $fout_nameviene sempre assegnato a uno fouto al nome specificato $foute, facoltativamente, al nome specificato viene sempre assegnato il valore di output della funzione. Per dimostrarlo ho scritto questo piccolo forloop:
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
Gioca con alcuni con nomi di variabili ed espansioni di parametri. Se hai una domanda, basta chiedere. Che esegue solo le stesse poche righe nella funzione già rappresentata qui. Vale la pena ricordare almeno che le variabili $ae si $bcomportano diversamente a seconda che siano definite al momento dell'invocazione o impostate già. Tuttavia, fornon fa quasi altro che formattare il set di dati e fornito da f(). Dare un'occhiata:
###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'
$ae$bsono variabili locali nella tuaffunzione. Potrestiexportaverli, ma questo sembra impreciso.