在我的shell环境中,我有别名和自定义函数。当我在emacs实例中(我总是使用emacs -nw
)执行shell命令(M-!
),我无法使用它们。这很合理,因为我想象它启动自己的子shell来执行这些操作...但是是否有一种方法(也许在我的.emacs
中)可以使这个工作?也许甚至涉及在执行任何shell命令之前默认引入一个环境?
在我的shell环境中,我有别名和自定义函数。当我在emacs实例中(我总是使用emacs -nw
)执行shell命令(M-!
),我无法使用它们。这很合理,因为我想象它启动自己的子shell来执行这些操作...但是是否有一种方法(也许在我的.emacs
中)可以使这个工作?也许甚至涉及在执行任何shell命令之前默认引入一个环境?
以下是我对一个相关问题的评论:
我认为M-x shell-command和M-x compile都通过调用call-process
在一个子 shell 中执行命令。请尝试在您的 .emacs 文件中添加以下代码(或者直接评估它):
(setq shell-file-name "bash")
(setq shell-command-switch "-ic")
我注意到在上述的评估之后,.bashrc
别名被用于 M-x shell-command 和 M-x compile,即:
M-x compile RET 你的别名 RET
应该就可以工作了。
我的环境:Emacs 24.1(预测试版本 rc1),OSX 10.7.3
-i
用于交互,而-c
告诉bash读取其后的任何命令(因此Emacs在shell调用中使用了什么)。 - jmdeldinalias python python27
and ~/.aliasExpand has
source ~/.alias
shopt -s expand_aliases
```替换了.bashrc文件中的所有别名。"最初的回答"
source ~/.alias
最终,我将以下内容添加到我的.emacs文件中:
(setenv "BASH_ENV" "~/.aliasExpand")
我尝试了Keith Flower的解决方案(使shell交互),但我得到了以下错误信息:
bash: 无法设置终端进程组(-1):不适当的ioctl设备
bash:此shell中没有作业控制
请注意,我是通过Glenn Jackman和Nicholas Dudebout的提示获得了这个错误。
如果您愿意冒所有shell拓展别名的风险,并且您不介意为每个emacs shell运行所有的.bashrc,那么您可以简化此操作,只需添加以下内容即可:
shopt -s expand_aliases
to your .bashrc and
(setenv "BASH_ENV" "~/.bashrc")
to your .emacs
(setenv "BASH_ENV" (expand-file-name "~/.bashrc"))
或者 (setenv "BASH_ENV" (substitute-in-file-name "$HOME/.bashrc"))
,这样就不需要使用 shopt
命令了。 - fengqishell-command
按照https://dev59.com/nGct5IYBdhLWcg3wQ7Qy#12228646中描述的技术,在执行命令前读取~/.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 "$@"
[ -z "$PS1" ]
返回true(表示非交互式shell),您的~/.bashrc
可能需要更改以定义非交互式别名。这是我为自己的环境采取的方法(虽然它很简单),我的环境在https://github.com/jcburley/UnixHome上可以找到。BASH_ENV=~/.bashrc emacs
,但某些程序专门使用“/bin/sh”。请注意不要更改原有的HTML标签格式。shopt -s expand_aliases
命令启用别名机制。这在非交互式 shell 中默认是未启用的。 - Nicolas Dudebout如果您直接设置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))
.bashrc
中,而不是.bash_profile
中。后者仅在登录shell中执行,前者在所有shell中都会执行。.bashrc
中并没有改变任何事情。 - Nicolas Dudebout
M-x!tty -s
显示代码1来证明)。 - Nicolas Dudebout