4.9 Managing User Services

The Shepherd can be used to manage services for an unprivileged user. First, you may want to ensure it is up and running every time you log in. One way to accomplish that is by adding the following lines to ~/.bash_profile (see Bash Startup Files in The GNU Bash Reference Manual):

if [[ ! -S ${XDG_RUNTIME_DIR-$HOME/.cache}/shepherd/socket ]]; then
    shepherd
fi

Then, we suggest the following top-level $XDG_CONFIG_HOME/shepherd/init.scm file, which will automatically load individual service definitions from ~/.config/shepherd/init.d:

(use-modules (shepherd service)
             ((ice-9 ftw) #:select (scandir)))

;; Send shepherd into the background
(perform-service-action root-service 'daemonize)

;; Load all the files in the directory 'init.d' with a suffix '.scm'.
(for-each
  (lambda (file)
    (load (string-append "init.d/" file)))
  (scandir (string-append (dirname (current-filename)) "/init.d")
           (lambda (file)
             (string-suffix? ".scm" file))))

Then, individual user services can be put in $XDG_CONFIG_HOME/shepherd/init.d/, e.g., for ssh-agent.

;; Add to your ~/.bash_profile:
;;
;; SSH_AUTH_SOCK=${XDG_RUNTIME_DIR-$HOME/.cache}/ssh-agent/socket
;; export SSH_AUTH_SOCK

(use-modules (shepherd support))

(define ssh-agent
  (service
    '(ssh-agent)
    #:documentation "Run `ssh-agent'"
    #:start (lambda ()
              (let ((socket-dir (string-append %user-runtime-dir "/ssh-agent")))
                (unless (file-exists? socket-dir)
                  (mkdir-p socket-dir)
                  (chmod socket-dir #o700))
                (fork+exec-command
                 `("ssh-agent" "-D" "-a" ,(string-append socket-dir "/socket"))
                 #:log-file (string-append %user-log-dir "/ssh-agent.log"))))
    #:stop (make-kill-destructor)
    #:respawn? #t))

(register-services (list ssh-agent))
(start-service ssh-agent)