In my shell environment I have aliases and custom functions. When I am in an instance of emacs (I always use emacs -nw
) and I execute a shell command (M-!
To get shell-command
to read ~/.bashrc
before executing the command per the technique described in https://stackoverflow.com/a/12228646/8869495, without potential side effects due to $BASH_ENV
being defined for your entire Emacs session, try this in your ~/.emacs.d/init.el
(or .emacs
) file:
;; I want M-! (shell-command) to pick up my aliases and so run .bashrc:
(setq shell-file-name "bash-for-emacs.sh") ; Does this: BASH_ENV="~/.bashrc" exec bash "$@"
(setq shell-command-switch "-c")
As described by the comment in the second line, also install (in your $PATH
) a script named bash-for-emacs.sh
that contains:
#!/bin/bash
BASH_ENV="~/.bashrc" exec bash "$@"
Note that your ~/.bashrc
might need to be changed to define non-interactive aliases even when [ -z "$PS1" ]
is true (which indicates a non-interactive shell). That's the approach I'm taking for my own environment (such as it is), which is at https://github.com/jcburley/UnixHome.
Also, this assumes you want to use Bash as your Emacs-spawned shell, as I do.
Below are my comments about what I think was a related question:
I think both M-x shell-command and M-x compile execute commands in an inferior shell via call-process. Try the following in your .emacs (or just evaluate):
(setq shell-file-name "bash")
(setq shell-command-switch "-ic")
I notice that after evaluation of the above, .bashrc aliases are picked up for use by both M-x shell-command and M-x compile, i.e
M-x compile RET your_alias RET
should then work.
My environment: Emacs 24.1 (pretest rc1), OSX 10.7.3
Source
We need to enable alias expansion in non-interactive shells, preferably only when they are called from emacs (to avoid causing subtle differences when we run other shells). What worked for me was to create two files: ~/.alias has all my aliases, e.g.
alias python python27
and ~/.aliasExpand has
source ~/.alias
shopt -s expand_aliases
I also, of course, replaced all my aliases in .bashrc with
source ~/.alias
Finally, I added this to my .emacs:
(setenv "BASH_ENV" "~/.aliasExpand")
I tried Keith Flower's solution (of making shells interactive), and I got
bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell
Note that I got this through Glenn Jackman's and Nicholas Dudebout's hints.
If you are willing to risk having all your shells have alias expansion and you don't mind running all your .bashrc for every emacs shell, you can simplify this to adding
shopt -s expand_aliases
to your .bashrc and
(setenv "BASH_ENV" "~/.bashrc")
to your .emacs
Have a read through http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files
For non-interactive shells, the only file that is sourced is the value of the BASH_ENV environment variable. You invoke emacs like BASH_ENV=~/.bashrc emacs
if emacs will use bash for shell commands -- some programs specifically use "/bin/sh"
Put the aliases and functions in .bashrc
, not .bash_profile
. The latter is only executed in login shells, the former is in all shells.