【问题标题】:Proper way to use a trap to exit a shell-script in ZSH?在 ZSH 中使用陷阱退出 shell 脚本的正确方法?
【发布时间】:2020-05-11 16:18:40
【问题描述】:

我无法让 Zshell 脚本中的陷阱函数在不退出 shell 的情况下工作。我有一个简单的倒数计时器,我希望能够使用 ^C 中断它,并且当我这样做时,我希望陷阱改变终端中的光标状态。

我的语法是:

#!/bin/zsh

trap 'tput cnorm; exit' INT TERM

我也试过了:

trap 'tput cnorm; kill -9 $$' INT TERM

两个中断都完全退出 shell。如何只退出脚本并返回命令行?

任何指导将不胜感激!

【问题讨论】:

  • 您是在采购脚本还是在单独的进程中执行它?
  • 我在进行更改时采购它,但一旦它工作,它将作为一个函数自动加载,以便在交互式 shell 中使用。
  • 您是否尝试捕捉EXIT 信号?
  • 如何赶上退出?你的意思是?它作为一个可执行文件工作,但我想将它作为一个函数自动加载到我的环境中。我的其他函数脚本都不是可执行的。

标签: shell command-line scripting zsh


【解决方案1】:

使用陷阱处理信号

TRAPINT() {
    echo "TRAPINT() called: ^C was pressed"
}

TRAPQUIT() {
    echo "TRAPQUIT() called: ^\\ was pressed"
}

TRAPTERM() {
    echo "TRAPTERM() called: a 'kill' command was aimed at this program's process ID"
}

TRAPEXIT() {
    echo "TRAPEXIT() called: happens at the end of the script no matter what"
}

for i in {1..9}; do
    echo ${i}
    sleep 1
done

对于所有这些TRAP[NAL]() 函数,如果最终命令是return 0(或者如果根本没有返回语句,那么代码将继续执行程序停止的地方,就好像信号被接受,被捕获一样, 并进行处理。如果该函数的返回状态为非零,则保留陷阱的返回状态,中断之前的命令执行。您可以通过return $((128+$1))返回相同的状态就好像信号没有被困住一样

至于你的 shell 被杀死的原因,这是因为调用 kill -9 $$ 会将信号 9 发送到与你的 shell 关联的进程 ID。信号 #9 或 SIGKILL 是陷阱无法处理的一种信号。如果程序真的需要立即停止,并且不允许进行清理,这有点像“最后的手段”。

【讨论】:

  • 啊!这就是问题所在!我现在明白了。我已切换到返回值非零的 TRAPINT,它按预期工作!谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-07
  • 2018-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-04
  • 2020-06-22
相关资源
最近更新 更多