MacOS 下 zsh 执行长时间命令完成后自动提醒
前言
最近正在使用 Warp 作为常用的终端,有一些细节体验做的真的很不错,无论是命令提示还是补全都很厉害。其中有一个细节我认为对于我来说非常实用,就是长时间执行完成之后的命令提醒。
举个例子🌰:当你在终端进行 make 编译或者打包镜像的时候,往往需要比较长的时间,而你一般不会一直等着它执行完成,而是执行完成之后就切到别的地方去工作(摸鱼)了,然后你无法及时知道命令执行完成了,而只能是不是过来看下执行情况。
而在 warp 执行命令完成之后,就有这样一个通知提醒,我就能时刻关注到命令什么时候执行完成了。
当然,这必须依赖于你使用 warp,但我们常常在 IDE 下方的命令行中执行命令,而非单独使用其他终端,因为切换窗口也比较麻烦。于是乎我就想,能否利用 zsh 来实现这个功能呢?
实现
1 | vim ~/.zshrc |
1 | # 设置要匹配的字符串 |
1 | source ~/.zshrc |
其实原理非常简单,就是通过 add-zsh-hook 的钩子,在执行命令之之前(当前命令执行结束)判断,上一个命令是否在我的匹配列表中,如果这个命令需要提示则使用 osascript
进行提示,其中通过 fc -lnr -1
获取上一个执行的命令。
使用者只需要在 string_to_match 数组中添加你需要进行提醒的命令就可以了,因为通常我们不希望所以执行的命令都有一个提醒,而只需要包含特定功能的命令的进行提醒就可以了。比如:只要包含 go build 字符的编译命令执行完成之后就进行提醒。
有关提示声音
其中,通知提示的声音可选项在 /System/Library/Sounds
目录下的文件名称,个人认为 Blow
还可以,其他声音有点小。当然如果你不需要声音提醒的话,去掉 sound name "Blow"
就可以了。
你还可以自定义声音,只需要将声音文件下载,并转换到 aiff
格式,并放到 ~/Library/Sounds
目录下就可以了,在脚本中只需要写文件名,不需要写后缀的 aiff
。
一般下载的格式是 wav,可以到 https://cloudconvert.com/wav-to-aiff 进行转换,当然网上有很多在线工具。
其他尝试与问题
- 我尝试过通过判断上一个命令的执行时间比如超过 10 秒的命令就才进行提示,但实际使用效果并不好,有时候 9 秒的命令就很尴尬,所以还是认为指定具体命令效果更好
osascript
还支持 alert,但效果一般,需要手动确认,还是通知更加合理,虽然通知有时候会被忽略,但开启声音之后我觉得就很不错了- 你还可以尝试将命令的内容放到通知的内容里面,提示会更加友好,对于我来说现在的提示足够了,所以我就没做
- 目前有一个小 bug,就是当使用完成一个命令之后,如果重新打开一个命令行窗口,就会有一个提示,这是由于打开命令行窗口 zsh 也会触发 add-zsh-hook,但好在问题也不大
- 多个终端同时跑可能会有冲突,但目前还没有发现
- 最后注意给到终端必要的通知权限