I'm trying to write a shell function to launch (spac)emacs, update packages, and then restart emacs in daemon mode.
I tried this, but it hangs:
emacs --daemon && emacsclient -e '(progn (configuration-layer/update-packages))'
Instead of trying to start emacs in daemon mode first and asking it to execute the package update, I'd recommend doing that after performing a scripted upgrade of the packages. To update the packages non-interactively, use the following:
emacs --batch -l ~/.emacs.d/init.el --eval="(configuration-layer/update-packages t)"
The key here is the
--batch switch for performing non-interactive operations via the emacs command.
-l switch loads the emacs configuration (including the Spacemacs library and configuration). Without this, emacs would not know what the
configuration-layer/update-packages function is.
--eval switch passes emacs a function you want to execute. In this case, passing
(configuration-layer/update-packages t) will call the
configuration-layer/update-packages function from Spacemacs with the argument
t. Passing the argument skips the interactive package update confirmation; it's only important that the argument be a truthy value.
Note that because of the manner in which Spacemacs updates packages, it will only prepare the packages for update when this command is run. The next time that emacs is started, it will actually go through the process of installing the packages, so if you run
emacs --daemon directly after this function, it may take longer than usual for the system to start up.
This is also why I recommend not starting emacs in daemon mode and having it evaluate the
configuration-layer/update-packages function: the package updates will only take effect when a new daemon is started.