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 c
sebelum 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
newval
adalah tidak ditugaskan untuk $c
inline karena oldval
diperluas 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 newval
ditugaskan 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 name
pada satu titik dan var
di 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 $ENV
argumen 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 export
sebagai lawan eval
jauh lebih aman.
Dalam contoh di atas f()
pertama memberikan $fout
yang ''
nol tali dan kemudian menetapkan params posisi ke tes untuk nama variabel yang valid. Jika kedua pengujian tidak lulus pesan dipancarkan ke stderr
dan nilai default fout
ditugaskan untuk $fout_name
. Terlepas dari tes, bagaimanapun, $fout_name
selalu ditugaskan untuk salah satu fout
atau nama yang Anda tentukan $fout
dan, dan opsional, nama yang Anda tentukan selalu diberi nilai output dari fungsi. Untuk menunjukkan ini, saya menulis for
lingkaran 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 $a
dan $b
berperilaku berbeda tergantung pada apakah mereka didefinisikan pada doa, atau sudah ditetapkan. Namun, for
hampir 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'
$a
dan$b
merupakan variabel lokal dif
fungsi Anda . Anda bisaexport
melakukannya, tetapi itu tampak samar.