为什么 emacsclient 在执行 'emacs --daemon' 后找不到套接字



这太令人困惑了,以至于emacsclient在bash:中执行emacs --daemon后说它找不到套接字

$ ps aux | grep emacs
shiangro         1744   0.0  0.0  2432784    604 s000  S+    1:03下午   0:00.00 grep emacs
$ /usr/local/bin/emacs --daemon
("emacs")
Starting Emacs daemon.
Restarting server
$ /usr/local/bin/emacsclient -t
emacsclient: can't find socket; have you started the server?
To start the server in Emacs, type "M-x server-start".
emacsclient: No socket or alternate editor.  Please use:
    --socket-name
    --server-file      (or environment variable EMACS_SERVER_FILE)
    --alternate-editor (or environment variable ALTERNATE_EDITOR)

我的.emacs:中有此设置

(server-start)
(setq server-socket-dir "~/.emacs.d/server")

它工作了,服务器文件~/.emacs.d/server/server就在那里,但emacsclient说它找不到套接字,太烦人了,我不得不用-s选项告诉他套接字文件。

我发现了这个棘手的问题,同时我想让emacs在每次使用crontab的◎reboot特殊字符串重新启动(启动)systerm后作为守护进程运行。

在这种情况下,cron成功启动了emacs服务器,服务器文件~/.emacs.d/server/server也在那里,但后来当我启动一个终端并尝试emacsclient -t时,它失败了,并抱怨找不到套接字文件!

虽然我每次执行emacsclient时都可以使用-s ~/.emacs.d/server/server来绕过这个问题,或者将emacsclient别名为emacsclient -s ~/.emacs.d/server/server,但有更好的方法来安慰我的心吗?

背景:

系统:Mac OS X 10.9.2

emacs:GNU emacs 24.3.1由自制安装

查找服务器套接字文件是一个棘手的问题,您可以使用lsof来查找它,然后使用grep来提取套接字路径/文件名。

lsof -c emacs | grep server | grep -E -o '[^[:blank:]]*$'

或者,在OSX上,当您希望运行/Application/Emacs时,您可以将lsof要查找的命令名更改为-c Emacs。即

lsof -c Emacs | grep server | grep -E -o '[^[:blank:]]*$'

您可以使用cut而不是杂乱的过滤grep(搜索非空白直到行结束[^[:blank:]]*$

lsof -c Emacs | grep server | cut -c70-

更好的是,挤压空隙并使用cut的场切割。

lsof -c Emacs | grep server | tr -s " " | cut -d' ' -f8

既然有了套接字(或者它是空的),就可以在emacsclient上进行有条件的启动,即

#!/bin/bash 
socket_file=$(lsof -c Emacs | grep server | tr -s " " | cut -d' ' -f8)
if [[ $socket_file == "" ]]; then        
    # Just run Emacs (with any arguments passed to the script)
    # It would be a good idea to parse the arguments and clean/remove
    # anything emacsclient specific. 
    # (ie. -e should be --eval for emacs)
    # note that emacsclient doesn't fix these args for you either
    # when using -a / --alternate-editor
    emacs $@ &
    # or on OSX
    /Application/Emacs.app/Contents/MacOS/Emacs $@ &
else
    emacsclient $@ -n -s $socket_file
fi

既然你已经完成了:

/usr/local/bin/emacs --daemon

服务器已启动。所以,你实际上并不需要:

(server-start)
(setq server-socket-dir "~/.emacs.d/server")

在.emacs中。当您采用这种方法时,服务器会被放置在/tmp/emacs502(或者其他数字)中。在linux上,emacsclient似乎不会在那里找到它(在这种情况下,我看到/tmp/emacs1920),因此"emacsclient-nw"可以工作。我正在OSX上使用HomeBrew进行尝试,就像你一样,我发现我必须使用进行连接

emacsclient -nw -s /tmp/emacs502/server

(如果您使用--deamon=name,那么您将在最后一行中使用"name"而不是"server"。)

emacsclient只有在我从命令行运行emacs时才能找到emacs服务器。如果我从Ubuntu启动器运行emacs,那么emacsclient将无法连接到服务器。

如果您想使用Emacs守护进程而不是服务器,请定义两个环境变量

export ALTERNATE_EDITOR="" export EDITOR=emacsclient

您可以在~/.bashrc~/.profile中添加这些环境变量。

如果ALTERNATE_EDITOR环境变量为空,则Emacs将运行其守护进程并连接到它。

我认为emacsclient只能在标准路径中查找特殊文件server,例如在/tmp/emacs1000中。如果更改此参数server-socket-dir,则应通过键-s将其告知emacsclient

macOS上,emacs套接字名称的计算如下:

export EMACS_SOCKET_NAME="${TMPDIR}/emacs$(id -u)/server"

根据CCD_ 32,环境变量CCD_ 33可以被设置为覆盖违约然而,这似乎在Homebrew环境中不起作用。我在我的.bashrc中有这个,它对我有效:

export EDITOR="emacsclient --tty"
export ALTERNATE_EDITOR="emacs --no-window-system"
case "$(uname -s)" in
    # ...
    Darwin*)
        export EMACS_SOCKET_NAME="${TMPDIR}/emacs$(id -u)/server"
        export EDITOR="${EDITOR} --socket-name ${EMACS_SOCKET_NAME}"
    ;;
esac

最新更新