summary
Emacs processes currently (since version=23?) can be run from a "normal"/non-Emacs commandline in 1 of 3 modes:
classic
. (AFAICS this is my usage--please correct if there is a preferred term.) This was for decades the only way to run Emacs, and still (IIUC, ICBW) the only way one can runemacs --debug-init
. I'll refer to such processes asclassics
.daemon
akaserver
. An Emacs daemon process can be started either byemacs --daemon
: starts a new daemon process (only)emacsclient --alternate-editor=''
: starts a client process, and also a new daemon process if one was not already running
client
: started withemacsclient
. Emacs client processes can be- GUI (in new window) if started with
--create-frame
- TUI (in same terminal) if started with
--tty
- GUI (in new window) if started with
From a commandline, one can normally easily discriminate clients from classics and daemons, since their process name=emacsclient
by default. However the default process name for both classics and daemons is emacs
:-(
So how to discriminate--from a commandline, i.e., not from within Emacs--between classic and daemon processes?
Elisp daemonp
allows one to query a running process regarding whether or not it is an Emacs daemon. This works cleanly from commandline if the process is a daemon, as illustrated below. But if the process is a classic, it fails if used as designed. So is there a clean, reliable way to discriminate between classic and daemon processes from a ("normal"/non-Emacs) commandline?
Note regarding potential answers: if your answer requires some interaction, please make it either
(preferred) in the "same commandline." Not sure if that's the correct usage (please correct if not); what I mean is something like
me@it: ~ $ your --code --here false
(acceptable) in a TUI Emacs in the same shell as the commandline, like (e.g.)
emacsclient --tty
details
testcase
Let's start with no emacs*
processes:
me@it: ~ $ date ; emacs --version
Mon Oct 9 23:50:18 MST 2017
GNU Emacs 24.4.1
...
FWIW, I'm running this on an up-to-date Debian (currently version=8.9) Linux, hence the somewhat downlevel Emacs.
me@it: ~ $ date ; pgrep -l emacs
Mon Oct 9 23:50:43 MST 2017
Now, start a clientless daemon:
me@it: ~ $ date ; emacs --daemon &
Mon Oct 9 23:51:05 MST 2017
... console spew follows ...
me@it: ~ $ date ; pgrep -l emacs
Mon Oct 9 23:51:20 MST 2017
8467 emacs
I can cleanly query this daemon process (unfortunately not by process#, but that's another question) with
me@it: ~ $ date ; emacsclient --eval '(if (daemonp) (message "true") (message "false"))'
Mon Oct 9 23:53:29 MST 2017
"true"
That, to me is "working as expected": particularly,
- response is correct
- no side effects
Kill that daemon (and cleanup after it--see this question for details):
me@it: ~ $ date ; pkill -9 emacs
Mon Oct 9 23:57:03 MST 2017
me@it: ~ $ date ; find ~/.emacs.d/ -name '*lock*'
Mon Oct 9 23:57:07 MST 2017
/home/me/.emacs.d/personal/.emacs.desktop.lock
me@it: ~ $ date ; find ~/.emacs.d/ -name '*lock*' | xargs rm
Mon Oct 9 23:57:17 MST 2017
Start a classic Emacs:
me@it: ~ $ date ; emacs --debug-init &
Mon Oct 9 23:57:47 MST 2017
me@it: ~ $ date ; pgrep -l emacs
Mon Oct 9 23:57:57 MST 2017
8692 emacs
Now try to query this classic process: very messy:
me@it: ~ $ date ; emacsclient --eval '(if (daemonp) (message "true") (message "false"))'
Mon Oct 9 23:58:19 MST 2017
emacsclient: connect: Connection refused
After that, I get my normal daemon startup console spew (which is a lot, since I'm running a Prelude config), followed by
Starting Emacs daemon.
Emacs daemon should have started, trying to connect again
ending with output that is only technically correct:
"true"
I.e., instead of telling me that the classic process is not a daemon, this creates me a daemon then tells me ... it's a daemon :-(
me@it: ~ $ date ; pgrep -l emacs
Mon Oct 9 23:58:35 MST 2017
8692 emacs
8747 emacs
So I guess I can use the above process to discriminate between classic and daemon processes: if I get yet another process name=emacs
, the 1st/tested process was classic, else daemon. But how to discriminate from a commandline
- not from within Emacs
- without non-trivial side effects, like creating a new/unwanted process
between classic and daemon processes?