Running Bash Subprocesses from Within Emacs

2018-10-10

I've struggled for years with using cool packages like rspec-mode because I use tools like rbenv to manage Ruby versions. The problem is that rbenv relies heavily on shell customizations to work, and when Emacs spawns a subprocess, bash is run as neither a login shell nor as an interactive shell. If you carefully read the section of the bash manual about invocation, you'll find that neither .bashrc nor .bash_profile are sourced for shells that are neither interactive nor login. Sure, you can tell Emacs to use -i when it invokes bash, but this causes other functions that rely on rapid subprocess creation to behave strangely, or at least be quite a bit slower.

But I kept reading the manual, and it turns out the solution lies in the use of the BASH_ENV environment variable, which, if specified, must point to a file that bash will happily source immediately after it is invoked. By creating a file that added $HOME/.rbenv/bin and $HOME/.rbenv/shims to my path, I was then able to (setenv "BASH_ENV" "/home/rpdillon/rbenvsetup.sh") in my initialization, I can now invoke rpsec from within Emacs on-demand, exactly as intended. And I also got to learn about BASH_ENV!