从vim执行的命令无法识别bash命令别名


96

我在Mac上使用bash,别名之一是这样的

alias gitlog='git --no-pager  log -n 20 --pretty=format:%h%x09%an%x09%ad%x09%s --date=short --no-merges'

但是当我这样做

 :! gitlog

我懂了

/bin/bash: gitlog: command not found 

我知道我可以在.gitconfig中添加这样的别名

[alias]
    co = checkout
    st = status
    ci = commit
    br = branch
    df = diff

但是我不想将所有bash别名添加到.gitconfig。那不是DRY。

有更好的解决方案吗?


如果别名位于.gitconfig中,则您无需在Bash别名中重复它们,并且使用git的所有内容都将知道它们,而不仅仅是Bash。因此,DRY令人钦佩,但是还有SPOT(单点真相),将SPOT放在正确的位置也意味着DRY也更容易。
乔纳森·莱夫勒


Answers:


113

除非它是交互式的,否则Bash不会加载您的.bashrc。用

:set shellcmdflag=-ic

使Vim的:!外壳像命令提示符一样运行。


6
编辑您的.vimrc文件(vim〜/ .vimrc),并将其放在行中(不包括:)
2011年

9
很好,但是我遇到了问题-如果启用交互模式(i标志),则可以很好地执行别名的shell命令,但是一旦命令执行完毕,vim就会退出,这是不可取的。例如,我尝试用shellcmdflag = -ic来:: ls:[4] +停止
vi〜

6
@Kevin:有没有办法通过交互式bash获得viw的正常行为?(执行命令,等待任何键,回到vim)
Mayeu 2012年

7
对我来说,在.vimrc中suspended (tty output)使用命令会导致我使用时git commit
has2k1 2013年

27
告诉Vim始终使用交互式shell可能会造成问题。更好的解决方案是弄清楚bash配置中的哪些内容设置了别名,以及如何将其移动到即使在非交互式shell中也可以加载的位置。例如,zshell只~/.zshrc为交互式shell 加载,但~/.zshenv为所有shell 加载,因此我将别名设置移到了那里,现在可以在Vim中使用。有关更多信息,请参见man zsh(或您的Shell的手册页)。
内森·朗

83

我知道这个问题以前已经“回答过”,但是我对答案有疑问。在Vim中不需要将shell 设置为交互式。请参见此线程以获取替代答案,而不必退出交互式外壳程序。

如果要使用非交互式外壳(默认情况下),但要扩展bash别名,请将别名定义放在文件中,例如.bash_aliases,并在此文件中显式启用别名扩展:

shopt -s expand_aliases  
alias la='ls -la'

然后将其添加到您的.vimrc中,这样每次您在vim中运行shell命令时,别名文件就会被读取:

let $BASH_ENV = "~/.bash_aliases"

该解决方案由“ Jakob”提出。请参阅下面的链接以获取原始信息。我在Mac OS X 10.9上对此进行了测试,并且可以正常工作!

vim-在交互模式下无法识别别名?


7
迄今为止最好的解决方案。我个人(在进行任何自定义交互模式检查之前)设置了$BASH_ENVvar .bashrc,因此我可以在应用程序中使用所有别名。
el.atomo

2
这可能是此页面上的最佳解决方案,因为更改范围仅限于Vim内。甚至可以走得更远,并且let $BASH_ENV="~/.vim/vim_bash",这将:!在Vim中用于所有调用。
Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeej 2015年

不幸的是,这在macOS 10.15.2默认shell zsh中不起作用。
Ben Quigley

8

请注意,根据bash点文件的配置方式,您可能需要使用-l而不是-i选项。这将启动该外壳作为登录外壳。


4
dreftymac写道:“为了使它对我有用,有必要做-lic选项,否则vim返回'找不到命令'”
dreftymac 2012年

8

我知道这可能是一个古老的问题,但是以上答案均无法满足我的要求。因此,对于那些通过谷歌搜索来到这里的用户以及(oh-my-)zsh用户而言:

我对此的解决方案就像将http://zsh.sourceforge.net/Intro/intro_3.html中的 .zshrc复制到.zshenv一样简单:

除非设置了-f选项,否则.zshenv的所有调用都源自shell的所有调用。它应包含用于设置命令搜索路径的命令,以及其他重要的环境变量。`.zshenv'不应包含产生输出或假定外壳已附加到tty的命令。

所以$ cp ~/.zshrc ~/.zshenv会做的事情。


这次真是万分感谢!只是要注意,如果您在文件中包含外壳程序别名,则可以从.zshenv中获取它们。像这样的东西: . $HOME/.aliases
scifisamurai

2

我对设置-i选项不太满意,因为它会产生很大的影响,而且我经常使用vim中的shell。相反,我要做的是:!bash -c ". ~/.alias; gitlog"


这似乎是最好的解决方案,但它对我不起作用。仍然说找不到命令
still_dreaming_1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.