简体   繁体   中英

meta programming in bash/zsh to reload shell script

I have three zsh script,

meta_zsh.sh ,

# meta_zsh.sh
meta_s() {
    eval 'echo "${(%):-%x} re-define s()"; s() { echo " calling s() ${(%):-%x}"; }'
}

script_zsh.sh and script_zsh_2.sh (the same content)

# script_zsh.sh and script_zsh_2.sh (the same content)
meta_s
s

in zsh execute below commands

$ . ./meta_zsh.sh; . ./script_zsh.sh; . ./script_zsh_2.sh

outputs

./meta_zsh.sh re-define s()
  calling s() ./script_zsh.sh
./meta_zsh.sh re-define s()
  calling s() ./script_zsh_2.sh

The question is, how to achieve same effect in bash?

I tried change to ${(%):-%x} to ${BASH_SOURCE[0]} or $0 , but neither works.

why bother?

After above meta_xx.sh sourced in ~/.zshrc (~/.bashrc),

I can type s in the shell to reload a recently source script, if meta_s is in it.

BASH_SOURCE is actually the stack of callers, with ${BASH_SOURCE[0]} being the current file, so you can use ${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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM