在我的shell环境中,我有别名和自定义函数。当我在emacs的实例(我总是使用emacs -nw)并执行shell命令(M-x!)时,我无法使用它们。这是有道理的,因为我想它启动它自己的子shell来做这些..但有没有办法(也许在我的.emacs中)让这个工作?也许即使它在执行任何shell命令之前默认采购环境?
答案 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
答案 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-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))
答案 5 :(得分:-3)
将别名和函数放在.bashrc
中,而不是.bash_profile
。后者仅在登录shell中执行,前者在所有shell中执行。