2

I want to write a script that "links" an emacs server to a certain directory. To do so I need to check all existing servers to be sure if a server with a specific name is running or not. Then the script can decide to start a new server, or not, before opening a file from that directory using emacsclient.

I have been looking around to find out how to list the existing emacs running servers, unsuccessfully though.

Is there anything like emacs --list-servers that I could use?

Cheers.

mrcl
  • 2,130
  • 14
  • 29
  • Could you potentially just use emacs' --eval options to evaluate elisp from the command line, such as inspecting the server-clients variable? – Dan LaManna Mar 20 '14 at 04:30

2 Answers2

2

Emacs stores the socket files for all running servers in ${TMPDIR}/emacs$(id -u), where $TMPDIR defaults to /tmp if unset. Find all running servers is as simple as listing all sockets in that directory.

In Bash, this would look roughly like

local serverdir="${TMPDIR:-/tmp}/emacs${UID}"
local -a servers
for file in ${serverdir}/*; do
  if [[ -S ${file} ]]; then
    servers+=("${file##*/}")  
  fi
done

echo "${servers[@]}"

The servers array now contains the names of all running Emacs servers, for use with emacslcient -s.

Edit: Since you're using Python apparently, the same in Python:

import os
from stat import S_ISSOCK

serverdir = os.path.join(os.environ.get('TMPDIR', '/tmp'),
                         'emacs{0}'.format(os.geteuid()))
servers = [s for s in os.listdir(serverdir)
           if S_ISSOCK(os.stat(os.path.join(serverdir, s)).st_mode)]
  • Very smooth! I got a solution in python checking the emacs running processes containing "--daemon=" as argument. But this one works way better! Cheers – mrcl Mar 20 '14 at 12:13
  • @mrcl You're welcome :) By the way, don't rely on the Emacs command line. Most stuff given on the command line can be changed later on from within Emacs. For instance, a user can explicitly start a server with `M-x server-start`, even without `--daemon`. In fact, that's how I start my Emacs server (I don't use `--daemon`). –  Mar 20 '14 at 12:28
  • 1
    @mrcl I added a Python example as well, for the sake of completeness :) –  Mar 20 '14 at 12:32
  • Nice, I was wondering... Is there any way to check if those sockets are necessarily from the servers? I mean, what if other emacs extension is running and use the same protocol, creating sockets in the this /tmp/emacs${UID} folder? – mrcl Mar 20 '14 at 19:55
  • The `server-socket-dir` variable is of import here. That's not necessarily `/tmp`, and your own config might affect it of course. You might use `socketdir=$(emacs --batch -l server --eval "(princ server-socket-dir)")`, but then that's still only going to work for Emacs instances using that same value (which may or may not be fine/reliable for you). – phils Mar 21 '14 at 00:10
  • You might also then use `lsof` to show the processes using the socket files. – phils Mar 21 '14 at 00:14
  • @mrcl I don't think that any other extension would write to this directory. If it did, it conflict with Emacs server regardless, because `emacsclient` assumes any socket in this directory to be a Emacs server socket. So I don't think that you need to take this into account in your script. –  Mar 21 '14 at 12:55
  • @phils `server-socket-dir` is a `defvar`, not a `defcustom`. As such, I don't think that it's intended to be changed. Actually, I'm pretty sure that changing the variable would actually break `emacsclient`, because the value of this variable is hardcoded in `emacsclient` (didn't try, though). Given this, I don't think that you actually need to look at the real value of the variable. Just taking its hardcoded value, as my answer does, should be sufficient. –  Mar 21 '14 at 12:59
  • Well I would think it should be a `defconst` if it's not intended to be changed. There's nothing wrong with changing a `defvar`. I agree that the hard-coded approach should be fine, though (as either approach is still making assumptions). – phils Mar 21 '14 at 22:05
  • @phils Good point. There are probably cases in which it's changed from Lisp, but let's say it's not intended to be changed by the user in their customizations. –  Mar 22 '14 at 10:13
1

If i didnt misunderstood you, you could just use emacsclient -a emacs. This will start emacs if a emacs server is not running else open emacsclient and connect.