36

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

4

6 回答 6

42

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

我认为M-x shell-commandM-x compile都通过调用进程在劣质 shell 中执行命令。在您的 .emacs 中尝试以下操作(或仅评估):

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

我注意到,在对上述内容进行评估之后,会选择 .bashrc 别名供M-xshell-command 和M-xcompile 使用,即

M-x编译RET your_alias RET

然后应该工作。

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

来源

于 2012-09-01T16:20:54.867 回答
2

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

对于非交互式 shell,唯一的来源文件是 BASH_ENV 环境变量的值。您调用 emacs 就像BASH_ENV=~/.bashrc emacs emacs是否将 bash 用于 shell 命令一样——某些程序专门使用“/bin/sh”

于 2012-09-01T14:40:07.663 回答
2

要在按照https://stackoverflow.com/a/12228646/8869495中描述的技术执行命令之前shell-command进行阅读,而不会由于为整个 Emacs 会话定义而产生潜在的副作用,请在您的(或)文件中尝试此操作:~/.bashrc$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可能需要更改以定义非交互式别名,即使[ -z "$PS1" ]是 true(这表示非交互式 shell)。这就是我为自己的环境(例如)采用的方法,位于https://github.com/jcburley/UnixHome

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

于 2018-10-13T23:37:37.547 回答
2

我们需要在非交互式 shell 中启用别名扩展,最好仅在从 emacs 调用它们时(以避免在我们运行其他 shell 时造成细微差异)。对我有用的是创建两个文件: ~/.alias 有我所有的别名,例如

alias python python27

和 ~/.aliasExpand 有

source ~/.alias
shopt -s expand_aliases

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

source ~/.alias

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

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

我尝试了 Keith Flower 的解决方案(使贝壳交互),我得到了

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

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

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

shopt -s expand_aliases

到你的 .bashrc 和

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

到你的 .emacs

于 2019-05-28T22:00:05.223 回答
0

直接设置shell-command-switch会大大shell-command增加速度(如果您使用许多(ba|z)sh插件),它由各种非交互式函数调用,如shell-command-to-string, eshell-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))
于 2021-06-19T11:42:41.020 回答
-3

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

于 2012-09-01T04:52:36.780 回答