macOS下如何组合leave与say命令实现内置语音提醒
问题原因
直接跑leave +0001 | say挂死,核心是Unix命令的输出缓冲规则在起作用:leave判断到自己的输出接的是管道不是终端时,会自动切到块缓冲——不会实时往外打内容,启动时设好闹钟的提示、到点的提醒文本全攒在内存缓冲区里,攒够一块才会往下传。下游的say等不到输入,就一直卡着,看起来像没启动、挂住了一样。
可用解决方法
方法1:stdbuf 改缓冲规则(最方便)
用stdbuf强制leave用行缓冲,打一行就往管道送一行,顺便过滤掉启动时的闹钟设置提示,只播提醒:
stdbuf -oL leave +0001 | grep --line-buffered "leave\!" | say
相关参数作用:
-oL:把leave的标准输出设成行缓冲,遇到换行就刷新缓冲区,实时送内容到管道grep --line-buffered:给grep也开行缓冲,避免grep自己攒内容不往下传- 匹配规则
leave\!会覆盖leave默认的所有提醒节点:提前5分钟、提前1分钟、正点、之后每分钟的催走提示。要是只想播正点的提醒,把匹配规则改成^Time to leave!就行。
方法2:script 模拟终端环境
要是用的旧版macOS没装stdbuf,直接用系统自带的script命令给leave伪造个伪终端环境,让它以为自己跑在真实终端里,自动开行缓冲:
script -q /dev/null leave +0001 | grep --line-buffered "leave\!" | say
相关参数作用:
-q:静默模式,不打印script自己的启动、退出提示/dev/null:把script默认生成的会话日志直接丢进黑洞,只透传leave的输出。
其他说明
- 这个用法和原生
leave的逻辑完全一致,要关提醒的话,先pgrep leave查到进程号,再kill -s KILL <进程号>杀掉就行 - 想换播报语音的话,给
say加-v参数指定就行,比如say -v Ting-Ting就是用中文普通话女声播报。
内容的提问来源于stack exchange,提问作者Bjarte Brandt
相关产品推荐
相关产品推荐

