I'm trying to get vim to execute the script I'm editing with a key mapping, say ctrl + x, so I used this in vimrc

:map <C-x> :!exec_file %<CR>

To pass the file name to a script I wrote which parses the extension and calls the appropriate interpreter, this works great so far.

However, I was wondering if I can call bash directly with the script name and have it execute it since most scripts I edit have a shebang line, so I tried this mapping instead:

:map <C-x> :!bash %<CR>

But it doesn't work, is it possible to execute a script by passing its name to bash ?

  • IIRC bash will try to execute Python scripts despite a different shebang line this way, so I'm not sure this actually makes sense. If your script file is executable, wouldn't :!% suffice? – Daniel Beck Feb 5 '13 at 10:55
  • @DanielBeck yes this is exactly what's happening, any way around that ? also not all scripts are executable and I don't want to chmod them... – mux Feb 5 '13 at 10:57
  • 1
    Do the same thing the OS does when trying to execute a script file: Parse the shebang line to determine the interpreter, then call it. Essentially what your exec_file does, but without having to rely on the extension. Maybe use this only as a fallback when there's no shebang line. FWIW, shebang lines generally only make sense when you want to make a script executable, as calling interpreters will file arguments always works. – Daniel Beck Feb 5 '13 at 10:59
  • Your bash mapping works here. I use the following mapping to invoke shebang, assuming the script is executable: map <f4> :!%:p<cr>. :p will expand to the full path of the script. – Thor Feb 5 '13 at 11:03
  • @Thor yes but not all scripts I edit are executable yet, sometimes I open vim and write the script and want to execute before chmod'ing it or I open a non-executable script, but I think I understand now why bash doesn't execute the script. – mux Feb 5 '13 at 11:08

Vim already uses a shell (see :set shell?) to execute the external command; scripts with shebang lines should work just fine. The canonical way to execute the current buffer is


(Prepending ./ to deal with the current directory not being part of PATH. This assumes that the script is already executable (:!chmod +x %, maybe done in a mapping / ftplugin.)

You can re-execute with just :!!. Also, there are fancier solutions for executing (partial, unsaved, etc.) buffer contents in external interpreters; check the plugins section of vim.org.

  • it seems that I have to chmod the script if I want this to work, thanks. – mux Feb 5 '13 at 11:12
  • Yeah, you probably need to chmod later anyway, so why not do this from the editor as you start writing it. – Ingo Karkat Feb 5 '13 at 11:19
  • I was trying to save the extra step, anyway, I think I will stick to the script way and maybe edit it to read the shebang line as suggested by Daniel, this allows me to execute scripts that are non-executable or don't have a shebang at all. – mux Feb 5 '13 at 11:24

seems that I have to chmod

no, you don't. if your executable is of the form

#! /bin/bash
ls -l

the mapping

:map <C-x> :! sh ./% <CR>

will do what you want, even though the file is not executable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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