すべての変数を割り当てて、同時に出力を書き込むだけです。
f() { c= ; echo "${c:=$(date): $((a=3)) $((b=4))}" ; }
今あなたがするなら:
f ; echo "$a $b $c"
あなたの出力は:
Tue Jul 1 04:58:17 PDT 2014: 3 4
3 4 Tue Jul 1 04:58:17 PDT 2014: 3 4
これは完全にPOSIXポータブルコードであることに注意してください。パラメータの展開により、同時変数割り当て+評価が数値のみ(またはなど)またはnullまたは存在しない値からのいずれかに制限されるため、または変数を任意の文字列に同時に設定して評価できないためc=
、最初は''
null文字列に設定しましたその変数にすでに値が割り当てられている場合。だから私は試す前にそれが空であることを確認するだけです。割り当てようとする前に空にしないと、拡張は古い値のみを返します。$((var=num))
c
ただ示すために:
sh -c '
c=oldval a=1
echo ${c:=newval} $((a=a+a))
'
###OUTPUT###
oldval 2
newval
はに展開されているため、インラインには割り当てられませんが、インライン算術割り当ては常に発生します。しかし、がなく、空または未設定の場合...$c
oldval
${word}
$((
=
))
$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
...次にnewval
、に割り当てられ、に展開され$c
ます。
これを行う他のすべての方法には、何らかの形の二次評価が含まれます。たとえば、ある場所と別の場所でf()
名前が付けられた変数に出力を割り当てたいとしましょう。現在書かれているように、これは呼び出し側のスコープで変数を設定しないと機能しません。ただし、別の方法では次のようになります。name
var
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"
以下でより適切にフォーマットされた例を提供しましたが、上記のように呼び出され、出力は次のとおりです。
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
または、別の$ENV
または引数を使用して:
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
おそらく、2回評価するときに正しく理解するのが最も難しいのは、変数が引用符を壊さず、ランダムコードを実行しないようにすることです。変数が評価される回数が増えるほど、変数は難しくなります。パラメータの拡張は、ここで非常に役立ちます。逆に使用export
する方eval
がはるかに安全です。
上記の例では、f()
最初$fout
に''
null文字列を割り当て、次に位置パラメータを設定して有効な変数名をテストします。両方のテストに合格しない場合、メッセージが送信されstderr
、デフォルト値のfout
がに割り当てられ$fout_name
ます。かかわらず、テストの、しかし、$fout_name
常にどちらかに割り当てられているfout
か、名前を指定し、$fout
必要に応じて、あなたの指定した名前は、常に関数の出力値を割り当てられている、と。これを実証するために、この小さなfor
ループを書きました。
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
変数名とパラメーター拡張を使用していくつかの機能を果たします。質問がある場合は質問してください。これは、すでにここで表されている関数の同じ数行のみを実行します。少なくとも、$a
と$b
変数は、呼び出し時に定義されているか、すでに設定されているかによって動作が異なることに言及する価値があります。それでも、for
はほとんど何もせず、データセットをフォーマットしてによって提供されf()
ます。見てください:
###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
あり$b
、f
関数のローカル変数です。あなたはexport
それらをすることができますが、それは大ざっぱなようです。