Emacs 如何在elisp中使用filter执行sudo命令
我想使用elisp执行一个特权命令,然后在看到某些输出时使用过滤器进行进一步处理 我的理解是,经过详尽的RTFM后,我可以:Emacs 如何在elisp中使用filter执行sudo命令,emacs,lisp,elisp,Emacs,Lisp,Elisp,我想使用elisp执行一个特权命令,然后在看到某些输出时使用过滤器进行进一步处理 我的理解是,经过详尽的RTFM后,我可以: 将默认目录设置为以“/sudo::/”开头的路径 调用start file process启动将在sudo下运行的进程 下面是我编写的一个函数,它试图做到这一点: (取消启动vpn(配置文件密码文件回调) “启动VPN连接,等待DHCP地址, 然后用它得到的地址调用回调。“ (let*((默认目录)/sudo::/tmp) (buff(获取缓冲区创建“*openvpn*”
默认目录设置为以“/sudo::/”开头的路径
start file process
启动将在sudo下运行的进程(取消启动vpn(配置文件密码文件回调)
“启动VPN连接,等待DHCP地址,
然后用它得到的地址调用回调。“
(let*((默认目录)/sudo::/tmp)
(buff(获取缓冲区创建“*openvpn*”)
(proc(启动文件进程“openvpn”*openvpn*
“/usr/local/sbin/openvpn”
(concat--config“配置文件)
(concat--auth user pass“密码文件”))
(设置过程过滤器程序
(λ(过程输出)
(消息“Got output:”output)
(let((ip(获取vpn ip地址输出)))
(当ip
(回拨ip((()()())))
当我运行此命令时,我在*Messages*
缓冲区中看到以下输出:
start-vpn
Tramp: Opening connection for root@localhost using sudo...
Tramp: Sending command `exec sudo -u root -s -H -p Password:'
Tramp: Waiting for prompts from remote shell
Tramp: Sending command `exec sudo -u root -s -H -p Password:'
Tramp: Found remote shell prompt on `localhost'
Tramp: Opening connection for root@localhost using sudo...done
(lambda (proc output) (message "Got output: " output) (let ((ip ...)) (if ip (progn ...))))
Got output:
…并且在函数创建的*openvpn*
缓冲区中没有输出
我不是elisp的专家,所以我怀疑我犯了一些愚蠢的错误。我对*消息*
缓冲区中的”(lambda(proc…
)也很好奇
感谢您的任何建议、批评或提示。首先,在消息缓冲区中看到
(lambda…
的原因是set process filter
返回过滤函数,因此start vpn
也返回过滤函数
您的消息
调用需要包含格式说明符才能实际显示输出:
(message "Got output: %s" output)
而(回调ip)
将无法工作,原因有二:
- Emacs Lisp有单独的函数和变量名称空间,因此
将调用函数(回调ip)
(该函数不存在),而您需要回调
调用存储在变量(funcall回调ip)
中的函数回调
- 一旦过了这个阶段,由于Emacs Lisp默认使用动态范围,当调用lambda函数时,
回调的绑定已经消失了 在Emacs 24中,您可以将
词法绑定设置为
,并且上面的代码应该可以工作。在任何情况下,您都可以显式使用t
宏:词法let
此宏使用黑魔法在lambda函数中保留(lexical-let ((callback callback)) (lambda (proc output) (message "Got output: " output) (let ((ip (get-vpn-ip-address output))) (when ip (funcall callback ip))))
的值回调