bash/zsh 中的元编程以重新加载 shell 脚本
meta programming in bash/zsh to reload shell script
我有三个zsh脚本,
meta_zsh.sh
,
# meta_zsh.sh
meta_s() {
eval 'echo "${(%):-%x} re-define s()"; s() { echo " calling s() ${(%):-%x}"; }'
}
script_zsh.sh
和script_zsh_2.sh
(内容相同)
# script_zsh.sh and script_zsh_2.sh (the same content)
meta_s
s
在 zsh 中执行以下命令
$ . ./meta_zsh.sh; . ./script_zsh.sh; . ./script_zsh_2.sh
产出
./meta_zsh.sh re-define s()
calling s() ./script_zsh.sh
./meta_zsh.sh re-define s()
calling s() ./script_zsh_2.sh
问题是,如何在bash中实现同样的效果?
我尝试将 ${(%):-%x}
更改为 ${BASH_SOURCE[0]}
或 [=21=]
,但均无效。
何必呢?
在以上 meta_xx.sh 来源之后 ~/.zshrc (~/.bashrc),
我可以在 shell 中输入 s
来重新加载最近的源脚本,
如果 meta_s
在其中。
BASH_SOURCE
实际上是调用者的堆栈,${BASH_SOURCE[0]}
是当前文件,所以你可以使用${BASH_SOURCE[1]}
:
$ cat meta.sh
meta_s() {
eval 'CALLER=${BASH_SOURCE[1]}; echo "$CALLER re-define s()"; s() { echo " calling s() $CALLER"; }'
}
$ cat s1.sh
meta_s
s
$ cat s2.sh
meta_s
s
$ . meta.sh ; . s1.sh ; . s2.sh
s1.sh re-define s()
calling s() s1.sh
s2.sh re-define s()
calling s() s2.sh
我有三个zsh脚本,
meta_zsh.sh
,
# meta_zsh.sh
meta_s() {
eval 'echo "${(%):-%x} re-define s()"; s() { echo " calling s() ${(%):-%x}"; }'
}
script_zsh.sh
和script_zsh_2.sh
(内容相同)
# script_zsh.sh and script_zsh_2.sh (the same content)
meta_s
s
在 zsh 中执行以下命令
$ . ./meta_zsh.sh; . ./script_zsh.sh; . ./script_zsh_2.sh
产出
./meta_zsh.sh re-define s()
calling s() ./script_zsh.sh
./meta_zsh.sh re-define s()
calling s() ./script_zsh_2.sh
问题是,如何在bash中实现同样的效果?
我尝试将 ${(%):-%x}
更改为 ${BASH_SOURCE[0]}
或 [=21=]
,但均无效。
何必呢?
在以上 meta_xx.sh 来源之后 ~/.zshrc (~/.bashrc),
我可以在 shell 中输入 s
来重新加载最近的源脚本,
如果 meta_s
在其中。
BASH_SOURCE
实际上是调用者的堆栈,${BASH_SOURCE[0]}
是当前文件,所以你可以使用${BASH_SOURCE[1]}
:
$ cat meta.sh
meta_s() {
eval 'CALLER=${BASH_SOURCE[1]}; echo "$CALLER re-define s()"; s() { echo " calling s() $CALLER"; }'
}
$ cat s1.sh
meta_s
s
$ cat s2.sh
meta_s
s
$ . meta.sh ; . s1.sh ; . s2.sh
s1.sh re-define s()
calling s() s1.sh
s2.sh re-define s()
calling s() s2.sh