这太令人困惑了,以至于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