3

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 ?

5
  • 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, 2013 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, 2013 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, 2013 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, 2013 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, 2013 at 11:08

2 Answers 2

10

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.

3
  • it seems that I have to chmod the script if I want this to work, thanks.
    – mux
    Feb 5, 2013 at 11:12
  • Yeah, you probably need to chmod later anyway, so why not do this from the editor as you start writing it. Feb 5, 2013 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, 2013 at 11:24
0

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .