如何让一个file watch script保持运行?

以下这个用了file notify的脚本,放到一个启动的有界面的emacs里面是可以工作的,但是直接运行它会立刻退出,file-notify-add-watch并不会让自己保持存活,有办法让它保持运行吗?

#!/usr/local/bin/emacs -Q --script
(require 'filenotify)

(defvar watchee "~/foo")

(file-notify-add-watch
 watchee
 '(change)
 (lambda (event)
   (with-temp-buffer
     ;; reverse the order as `insert-file-contents' always insert at position 0
     (insert-file-contents (concat default-directory "tail"))
     (insert-file-contents watchee)
     (insert-file-contents (concat default-directory "head"))
     (write-file (concat default-directory "bar")))
   (message (format "[%s]\nfile generated." event))))

用daemon做保持?

会报错说已经有server在运行(有个使用中的emacs)

你可以单独开一个emacs daemon掌管杂物emacs --daemon=maid,用emacsclient --socket-name=maid 连接上去。或者你可以直接把file watch挂在主daemon上,然后回调里用async这个包执行任务(JS传统艺能)

1 个赞

这个主意还不错,只是脚本里写#!/usr/local/bin/emacsclient --socket-name=maid只会打开这个文件,怎么让它自动eval-buffer?

不需要这个,file-notify这些东西都是不block的,瞬间就完成了,但是会收到后续的文件变动(如果emacs没退出)。要是它是block住的我一主帖里的脚本应该是可以工作的。可能可以改成block的,不过它的源码我看不懂。

我是怕回调block emacs

既然挂daemon了,直接用emacs --daemon=maid -l init-maid.el之流的载入函数不就好了。file watch script改成用eval调用已经加载好的函数

这样可以是可以,但是在server启动的时候我可能是不知道要run哪些脚本的,最好是server就启个空白的,想跑哪个脚本到“运行时”再决定。

感觉把问题搞复杂了,感觉还是从解决 file-notify为什么没有hold住自己的进程 这个角度是正道。不过暂时看不懂它的代码,先放着吧。。

我意思是daemon启动的时候载入函数的定义,运行script就执行函数

因为file notify是注册回调啊。。batch模式下执行完所有函数emacs就退出了,他不会给你做persistence的

理论上你用死循环是可以keep emacs running,不过那样没法执行异步回调


(maphash (lambda (k v) (print k) (print v)) file-notify-descriptors)

emacs监听文件修改的方式好像是用一个hashtable保存相应的信息

关键的点是 这个hashtable 是所有emacs进程共享的吗?

从现在来看 应该不是共享的 每个emacs进程都有他自己的hashtable

所以 这个方法 无解

你可以用emacs – [fg-] daemon 开启一个前台或后台服务

也可以用elnode开个端口(这个有点难欧)