私のスクリプト.bash_functions.test
で選択し、スクリプトを呼び出しました。.bash_functions
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
関数を実行すると、test1
次のようになります。
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
最後に、スクリプトを再インポートしてtest1
関数を再実行すると、次のようになります。
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
実際、私はSource
最初のソース呼び出しだけでなく、組み込み関数と2番目のソース呼び出しでも私のsource
関数を使用しています。
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
何が起こるのか?
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
なぜこのように動作しますか?
ベストアンサー1
declare
/typeset
なしで-g
型を設定することに加えて、現在の範囲の変数を宣言します。
ここでは関数内で実行されるdeclare -A audioExtension=(...)
ため、変数はその関数に対してローカルで宣言されるため、一度返されるとその定義は失われます。Source
audioExtension
Source
typeset -Ag audioExtension=(...)
常にグローバルスコープで変数を宣言するように変更できます(typeset -g
変数がローカルになるのを防ぐzsh / mksh / yashとは異なります(タイプ/プロパティと値のみを更新します)Source
。bash vs zsh: スコープと `typeset -g`詳細はこちら)。
ksh93
代わりに使用する場合(連想配列構文を借りたbash
シェル)、関数を次のように定義できます。bash
Source
Source() {
...
}
反対:
function Source {
...
}
ksh93でfunc() cmd
Bourneスタイルの構文を使用して定義された関数にはローカルスコープはありませんfunction func {
。変化のないローカル範囲(ここのみ一つグローバルスコープと一つローカルスコープのスタックではなく、ローカル関数固有のスコープ)。
(およびローカルスコープを持つ他のシェル)には、新しいスコープを導入せずにbash
機能を持つ同様の方法はありません。alias
同様の選択肢があります。
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(コードが拡張されると、エイリアスも拡張されます。読む、まだではありません処刑された)。
機能的なアプローチと比較すると、機能的な違いがあります。
Source ./myfile | other-cmd
どちらも時間を測定しsource myfile
、関数メソッドでwhileother-cmd
に拡張されるので、time source ./myfile | other-cmd
timingを渡しますsource ./myfile
。
使用しても効果はありません(timeキーワードの代わりにスタンドアロンユーティリティがsource=(time source); "${source[@]}" /some/file
呼び出されます)。time
bash