11

In Vim, when I run this command :!bash -c "ll", I get this error message bash: ll: command not found. ll is an alias in my ~/.bashrc file. If I just enter ll from bash it works. I created a ~/.bash_profile file and added the following to it:

if [ -f ~/.bashrc ]; then
   source ~/.bashrc
fi

I looked at my ~/.profile file and saw that it already had this at the beginning:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

I even tried setting bash to run in interactive mode, and it still won't recognize my aliases. If I use ls instead of ll, it works fine, since ls is not a custom alias.

1
  • The simplest solution is to add -i to the shellcmdflag setting, e.g. :set shellcmdflag=-ic. This makes sure the spawned shell is an interactive shell which reads your aliases. Commented Apr 22, 2020 at 6:13

3 Answers 3

11

Your issue is with bash and not with vim. The problem is that when you run !<cmd> in vim or /bin/bash -c <cmd> from another shell you are launching an instance of bash in non-interactive mode. In non-interactive mode alias are not expanded and you get this error. I don't know if you'd be able to enable the shell option expand_aliases from these types of situations since you're back into a non-interactive shell when you invoke !.

If you try to start an interactive shell it will put the vim process in the background after your command executes.

!/bin/bash -i -c ll
1
  • How can the blame be put on bash :)
    – mtk
    Commented Apr 21, 2020 at 12:04
5

Here's a strategy I use for this that utilizes the BASH_ENV which you can read about in man bash (and below). This strategy focuses specifically on what I want made available in vim.

When  bash  is started non-interactively, to run a shell script, for example,
it looks for the variable BASH_ENV in the environment, expands its value if it
appears there, and uses the expanded value as the name of a file to read and
execute.  Bash behaves as if the following command were executed:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

So, in your vimrc, you can do something like:

let $BASH_ENV="~/.vim/vim_bash"

In vim_bash you have content like this:

#!/bin/sh
shopt -s expand_aliases  
alias ll='ls -la'
alias foo='bar'
alias you='get the idea'

And that's really all there is to it. Now in vim you can do !ll

If you really did want to use your entire .bashrc you'd have to make sure you add shopt -s expand_aliases in it.

2

There's a bunch of different plugins for that. For example, vim-run-interactive.

But today you can also use :help :terminal. Or use GNU Screen or tmux. Or just split windows in your terminal emulator.

Not the answer you're looking for? Browse other questions tagged or ask your own question.