Cukup tetapkan semua variabel dan tulis output pada saat yang sama.
f() { c= ; echo "${c:=$(date): $((a=3)) $((b=4))}" ; }
Sekarang jika Anda melakukannya:
f ; echo "$a $b $c"
Output Anda adalah:
Tue Jul 1 04:58:17 PDT 2014: 3 4
3 4 Tue Jul 1 04:58:17 PDT 2014: 3 4
Perhatikan bahwa ini sepenuhnya kode portabel POSIX. Saya awalnya ditetapkan c=ke ''string nol karena ekspansi parameter membatasi penugasan variabel bersamaan + evaluasi untuk hanya numerik (seperti $((var=num))) atau dari nilai nol atau tidak ada - atau, dengan kata lain, Anda tidak dapat secara bersamaan mengatur dan mengevaluasi variabel ke string yang arbitrer jika variabel itu sudah diberi nilai. Jadi saya hanya memastikan bahwa itu kosong sebelum mencoba. Jika saya tidak mengosongkan csebelum mencoba untuk menetapkan ekspansi itu hanya akan mengembalikan nilai lama.
Hanya untuk menunjukkan:
sh -c '
c=oldval a=1
echo ${c:=newval} $((a=a+a))
'
###OUTPUT###
oldval 2
newvaladalah tidak ditugaskan untuk $cinline karena oldvaldiperluas ke ${word}, sedangkan inline $((aritmatika =tugas ))selalu terjadi. Tetapi jika $c tidak ada oldval dan kosong atau tidak disetel ...
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
... kemudian newvalditugaskan dan diperluas ke $c.
Semua cara lain untuk melakukan ini melibatkan beberapa bentuk evaluasi sekunder. Sebagai contoh, katakanlah saya ingin menetapkan output f()ke variabel bernama namepada satu titik dan vardi titik lain. Seperti yang ditulis saat ini, ini tidak akan berfungsi tanpa mengatur var dalam ruang lingkup penelepon. Namun, cara yang berbeda dapat terlihat seperti ini:
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"
Saya telah memberikan contoh yang diformat lebih baik di bawah ini, tetapi, disebut seperti di atas, keluarannya adalah:
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
Atau dengan $ENVargumen atau perbedaan :
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
Mungkin hal paling sulit untuk dilakukan dengan benar ketika mengevaluasi dua kali adalah memastikan bahwa variabel tidak memecah tanda kutip dan mengeksekusi kode acak. Semakin banyak variabel dievaluasi semakin sulit. Ekspansi parameter sangat membantu di sini, dan menggunakan exportsebagai lawan evaljauh lebih aman.
Dalam contoh di atas f()pertama memberikan $foutyang ''nol tali dan kemudian menetapkan params posisi ke tes untuk nama variabel yang valid. Jika kedua pengujian tidak lulus pesan dipancarkan ke stderrdan nilai default foutditugaskan untuk $fout_name. Terlepas dari tes, bagaimanapun, $fout_nameselalu ditugaskan untuk salah satu foutatau nama yang Anda tentukan $foutdan, dan opsional, nama yang Anda tentukan selalu diberi nilai output dari fungsi. Untuk menunjukkan ini, saya menulis forlingkaran kecil ini :
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
Memainkan beberapa dengan nama variabel dan ekspansi parameter. Jika Anda memiliki pertanyaan, tanyakan saja. Itu hanya menjalankan beberapa baris yang sama dalam fungsi yang sudah diwakili di sini. Perlu disebutkan setidaknya bahwa variabel $adan $bberperilaku berbeda tergantung pada apakah mereka didefinisikan pada doa, atau sudah ditetapkan. Namun, forhampir tidak melakukan apa-apa selain memformat kumpulan data dan disediakan oleh f(). Lihat:
###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'
$adan$bmerupakan variabel lokal diffungsi Anda . Anda bisaexportmelakukannya, tetapi itu tampak samar.