Home

Awesome

Melpa Status Melpa Stable Status NonGNU ELPA Status Build Status <a href="https://www.patreon.com/sanityinc"><img alt="Support me" src="https://img.shields.io/badge/Support%20Me-%F0%9F%92%97-ff69b4.svg"></a>

exec-path-from-shell

A GNU Emacs library to ensure environment variables inside Emacs look the same as in the user's shell.

Motivation

Ever find that a command works in your shell, but not in Emacs?

This happens a lot on OS X, where an Emacs instance launched as a GUI app inherits a default minimal set of environment variables that are probably not the ones you see in a terminal window. Similarly, if you start Emacs as a daemon from systemd or launchd, it will run with a default set of environment variables.

This library solves this problem by copying important environment variables from the user's shell: it works by asking your shell to print out the variables of interest, then copying them into the Emacs environment.

Compatibility

Supported shells:

Note that shell variables which have not been exported as environment variables (e.g. using the "export" keyword) may not be visible to exec-path-from-shell.

If you experience issues, enable the variable exec-path-from-shell-debug before runnin functions from the package: this will produce detailed logging in *Messages* about the shell command line and output.

Installation

Installable packages are available via MELPA: do M-x package-install RET exec-path-from-shell RET.

Alternatively, download the latest release or clone the repository, and install exec-path-from-shell.el with M-x package-install-file.

Usage

Add the following to your init.el (after calling package-initialize):

(when (memq window-system '(mac ns x))
  (exec-path-from-shell-initialize))

This sets $MANPATH, $PATH and exec-path from your shell, but only when executed in a GUI frame on OS X and Linux.

If you launch Emacs as a daemon from systemd or similar, you might like to use the following snippet:

(when (daemonp)
  (exec-path-from-shell-initialize))

You can copy values of other environment variables by customizing exec-path-from-shell-variables before invoking exec-path-from-shell-initialize, or by calling exec-path-from-shell-copy-env, e.g.:

(exec-path-from-shell-copy-env "PYTHONPATH")

This function may also be called interactively.

The author uses the following configuration snippet before calling exec-path-from-shell-initialize:

(require 'exec-path-from-shell)
(dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO" "LANG" "LC_CTYPE" "NIX_SSL_CERT_FILE" "NIX_PATH"))
  (add-to-list 'exec-path-from-shell-variables var))

Setting up your shell startup files correctly

Note that your shell will inherit Emacs's environment variables when it is run by exec-path-from-shell -- to avoid surprises your config files should therefore set the environment variables to their exact desired final values, i.e. don't do this:

export PATH=/usr/local/bin:$PATH

but instead do this:

export PATH=/usr/local/bin:/usr/bin:/bin

To be safe, exec-path-from-shell starts an interactive (and login) shell by default, but this can be much slower than necessary. Interactive shells often have fancy features enabled that are only helpful when one interacts directly with the shell, and this can frequently cause startup time to exceed 750ms. This can be avoided:

To learn more about how popular shells load start-up files, read this helpful article.

Making exec-path-from-shell faster

If evaluation takes more than exec-path-from-shell-warn-duration-millis (500ms by default) then exec-path-from-shell will print a warning.

Further help

<hr>

💝 Support this project and my other Open Source work via Patreon

💼 LinkedIn profile

✍ sanityinc.com

🐦 @sanityinc