метапрограммирование в bash / zsh для перезагрузки сценария оболочки - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть три сценария 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]} или $0, но ни один из них не работает.

Зачем беспокоиться?

После того как вышеописанный meta_xx.sh получен в ~ / .zshrc (~ / .bashrc),

Я могу набрать s в оболочке для перезагрузки недавно исходного скрипта, если в нем meta_s.

1 Ответ

1 голос
/ 21 сентября 2019

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
...