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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12224909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 03:09:57  来源:igfitidea点击:

Is there a way to get my emacs to recognize my bash aliases and custom functions when I run a shell command?

bashshellemacsenvironment-variables

提问by Palace Chan

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-!) I cannot use them. This makes sense since I imagine it launches it's own subshell to do these... but is there a way (maybe in my .emacs) to get this to work? Perhaps even if it involved sourcing an environment by default before executing any shell command given?

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

回答by Keith Flower

Below are my comments about what I think was a related question:

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

I think both M-xshell-commandand M-xcompileexecute commands in an inferior shell via call-process. Try the following in your .emacs (or just evaluate):

我认为M-xshell-commandM-xcompile 都通过 call-process 在劣质 shell 中执行命令。在您的 .emacs 中尝试以下操作(或只是评估):

(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-xshell-command and M-xcompile, i.e

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

M-xcompile RETyour_aliasRET

M-x编译RETyour_aliasRET

should then work.

然后应该工作。

My environment: Emacs 24.1 (pretest rc1), OSX 10.7.3

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

Source

来源

回答by James Craig Burley

To get shell-commandto read ~/.bashrcbefore executing the command per the technique described in https://stackoverflow.com/a/12228646/8869495, without potential side effects due to $BASH_ENVbeing defined for your entire Emacs session, try this in your ~/.emacs.d/init.el(or .emacs) file:

要在按照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")

As described by the comment in the second line, also install (in your $PATH) a script named bash-for-emacs.shthat contains:

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

#!/bin/bash

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

Note that your ~/.bashrcmight 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.

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

Also, this assumes you want to use Bash as your Emacs-spawned shell, as I do.

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

回答by Ethan Bradford

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.

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

alias python python27

and ~/.aliasExpand has

和 ~/.aliasExpand 有

source ~/.alias
shopt -s expand_aliases

I also, of course, replaced all my aliases in .bashrc with

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

source ~/.alias

Finally, I added this to my .emacs:

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

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

I tried Keith Flower's solution (of making shells interactive), and I got

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

bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell

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

Note that I got this through Glenn Hymanman's and Nicholas Dudebout's hints.

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

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

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

shopt -s expand_aliases

to your .bashrc and

到您的 .bashrc 和

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

to your .emacs

到您的 .emacs

回答by glenn Hymanman

Have a read through http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

通读一下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 emacsifemacs will use bash for shell commands -- some programs specifically use "/bin/sh"

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

回答by Barmar

Put the aliases and functions in .bashrc, not .bash_profile. The latter is only executed in login shells, the former is in all shells.

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