有没有办法让我的emacs在运行shell命令时识别我的bash别名和自定义函数?

时间:2012-09-01 04:31:07

标签: bash shell emacs environment-variables

在我的shell环境中,我有别名和自定义函数。当我在emacs的实例(我总是使用emacs -nw)并执行shell命令(M-x!)时,我无法使用它们。这是有道理的,因为我想它启动它自己的子shell来做这些..但有没有办法(也许在我的.emacs中)让这个工作?也许即使它在执行任何shell命令之前默认采购环境?

6 个答案:

答案 0 :(得分:32)

以下是我对我认为相关问题的评论:

我认为 Mx shell-command Mx 编译通过调用在劣质shell中执行命令处理。在.emacs中尝试以下内容(或仅评估):

(setq shell-file-name "bash")
(setq shell-command-switch "-ic")

我注意到在评估了上述内容后,.bashrc别名被 M-x shell-command和 M-x 编译使用,即

M-x 编译 RET your_alias RET

然后应该工作。

我的环境:Emacs 24.1(预测试rc1),OSX 10.7.3

Source

答案 1 :(得分:2)

阅读http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

对于非交互式shell,唯一获取的文件是BASH_ENV环境变量的值。你调用像BASH_ENV=~/.bashrc emacs 这样的emacs,如果 emacs将使用bash进行shell命令 - 某些程序专门使用“/ bin / sh”

答案 2 :(得分:2)

按照https://stackoverflow.com/a/12228646/8869495中描述的技术在执行命令之前让shell-command~/.bashrc,而不会因整个Emacs会话中定义$BASH_ENV而产生潜在的副作用,请在您的~/.emacs.d/init.el(或.emacs)文件中进行尝试:

;; 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")

如第二行中的注释所述,还(在您的$PATH中)安装名为bash-for-emacs.sh的脚本,该脚本包含:

#!/bin/bash

BASH_ENV="~/.bashrc" exec bash "$@"

请注意,即使~/.bashrc为true(表示非交互式shell),也可能需要更改[ -z "$PS1" ]才能定义非交互式别名。这就是我针对自己的环境(例如,https://github.com/jcburley/UnixHome)所采用的方法。

此外,这假设您像我一样想要使用Bash作为Emacs生成的外壳。

答案 3 :(得分:1)

我们需要在非交互式外壳中启用别名扩展,最好仅在从emacs中调用它们时才可以使用(为了避免在运行其他外壳时引起细微的差异)。对我有用的是创建两个文件:〜/ .alias具有我的所有别名,例如

alias python python27

和〜/ .aliasExpand具有

source ~/.alias
shopt -s expand_aliases

我当然也将.bashrc中的所有别名替换为

source ~/.alias

最后,我将其添加到我的.emacs中:

(setenv "BASH_ENV" "~/.aliasExpand")

我尝试了Keith Flower的解决方案(使壳互动),并且得到了

  

bash:无法设置终端进程组(-1):设备的ioctl不适当   bash:此shell中无作业控制

请注意,我是通过Glenn Jackman和Nicholas Dudebout的提示得到的。

如果您愿意冒险让所有shell都具有别名扩展名,并且不介意为每个emacs shell运行所有.bashrc,则可以将其简化为添加

shopt -s expand_aliases

到您的.bashrc和

(setenv "BASH_ENV" "~/.bashrc")

到您的.emacs

答案 4 :(得分:0)

直接设置 shell-command-switch 会显着使 shell-command 变得更加缓慢(如果您使用许多 (ba|z)sh 插件),它会被各种非交互式函数调用,例如 shell-command-to-stringeshell-remote-command,... 以及来自其他函数的大量调用,所有这些都不需要 .bashrc.zshrc

例如,在我的机器上(也可能是你的机器):

(benchmark-elapse (let ((shell-command-switch "-c")) (shell-command "")))
0.005170422
(benchmark-elapse (let ((shell-command-switch "-ic")) (shell-command "")))
0.242628824
;; Empty ~/.zshrc: 0.168341049

因此,我们应该选择仅在以交互方式调用 shell-command 时才使用交互式 shell 的方法

;;;###autoload
(defun my-shell-command-interactive-a (fn &rest args)
  "Use interactive shell for `shell-command' when invoked interactively.
Setting the \"-i\" switch all the time will significantly slow
down `shell-command' because there may too many files to source."
  (let ((shell-command-switch (if (called-interactively-p 'interactive)
                                  ;; Replace the first "-"
                                  (replace-regexp-in-string
                                   "\\(-\\).*\\'"
                                   "-i"
                                   shell-command-switch
                                   nil
                                   nil
                                   1)
                                shell-command-switch)))
    (apply fn args)))

(dolist (cmd '(shell-command async-shell-command)) 
   (advice-add cmd :around #'my-shell-command-interactive-a))

答案 5 :(得分:-3)

将别名和函数放在.bashrc中,而不是.bash_profile。后者仅在登录shell中执行,前者在所有shell中执行。