退出钩子在Bash和ZSH上工作

时间:2013-08-14 00:23:40

标签: bash shell zsh

我需要创建一个脚本,基本上设置一些env变量,启动一个子shell,当退出时,运行一些额外的代码,作为一个钩子。它需要在Bash和ZSH上工作,我知道也许我应该维护两个不同的脚本。

我需要它的原因是创建某种 bootstrap 脚本。例如,我使用两个函数startexit创建一个名为 Bootstrap.sh 的文件,当我运行脚本时,应该调用start并且一个新的子shell被激活。当子shell退出时,exit最终被调用。例如:

# Bootstrap.sh
start() {
    export CUSTOM_VAR="hello world"
}

exit() {
    echo "byebye"
}
  

$ bootstrap
  $#找到“Bootstrap.sh”,加载它然后调用“start”函数
  (myenv)$ echo $ CUSTOM_VAR
  你好世界
  (myenv)$退出
  byebye#这是我的退出挂钩
  $#回到“普通”shell

我正在使用this script来测试钩子,这是基于改进Python virtualenv的建议。在这个文件中,我尝试使用trap(a)和TRAPEXIT(b),但没有一个工作:

# (a), the "bash way", I think
my_hook() {
    echo "exit hook called"
}
trap my_hook EXIT
exec "${@:-$SHELL}"
# (b), as explained in ZSH documentation
# http://zsh.sourceforge.net/Doc/Release/Functions.html
TRAPEXIT() {
    echo "exit hook called"
}
exec "${@:-$SHELL}"

那么,我怎么能这样做(如果可能的话,在ZSH和Bash中)?

2 个答案:

答案 0 :(得分:2)

根据ZSH手册页,ZSH还支持trap内置版;就是这样,

trap 'any code here' EXIT

也适用于ZSH,并且你可以使用函数名作为代码字符串。

如果你需要包装exec,以下内容应该同时适用于bash和zsh

function exec {
    echo "Execcing"
    builtin exec "$@"
}

答案 1 :(得分:1)

问题是最后的'exec'。这(显然)不算作退出。当然,替换过程不会继承shell的退出处理程序。

解决方案:替换

exec "${@:-$SHELL}"

通过

"${@:-$SHELL}"

PS:我说显然是,因为我从来不知道它是否会(算作EXIT,我的意思)。我不得不尝试一下,但是有理由认为,exec与退出无关。该过程仅在“{@: - $ SHELL}”终止时退出。