According to the documentation for shellescape in vim:

shellescape({string}, [, {special}])      shell escape()

Escape {string} for use as a shell command argument.
For other systems, it will enclose {string} in single quotes and replace all "'" with "'\''".

Is there a function that will escape the same characters for the shell without enclosing {string} in single quotes?

  • I'm curious why you would need this? Jan 10, 2017 at 21:27
  • 1
    You could use shellescape and then strip them out with substitute.
    – Tumbler41
    Jan 10, 2017 at 22:01
  • @Carpetsmoker I noticed from the earlier question (vi.stackexchange.com/questions/10851/…) when I ran the command from inside vim, that it would put single quotes around the argument passed to my node.js script...and that the script didn't work properly when the quotes were passed.
    – leeand00
    Jan 10, 2017 at 22:05
  • 4
    The problem with using shellescape() and then removing the quotes is that you're no longer escaping anything :-) This may be a problem down the line if you have arguments with spaces in them and the like. I suspect that the problem is that you're passing two or more arguments to shellescape? (e.g something like shellescape(a:argA . ' ' . a:argB)? You should call it for every argument: shellescape(a:argA) . ' ' . shellescape(a:argB) Jan 10, 2017 at 22:21
  • 1
    Could you post an example of your system() call in addition to your use of shellescape()? @Carpetsmoker is more than likely right that you're running shellescape() on your entire argument list instead of on individual arguments. The only other issue I've encountered with shellescape() is when escaping an argument that already has an escaped ', such as JSON strings.
    – Tommy A
    Jan 11, 2017 at 4:52

1 Answer 1


A very long time ago, long before shellescape(), and I don't remember if escape() existed at that time, I wrote a function with the aim of running external commands from vim. Now it's shipped with my lh-vim-lib library, on vim.org we may find a trace of it in my system-tools set of scripts.

Any way, I copy-paste its documentation and its code, I can't tell whether it'll be of any help to you, you'll have to check.

The doc.

                                                *lh#path#fix()*                   {{{3
lh#path#fix({pathname} [,{shellslash} [,{quote-char}]]~
Discl.: This function is the old |system-tools|' |FixPathName| moved to lh-vim-lib.

This function corrects the {a:pathname} passed in parameter and, returns the
newly fixed pathname that will be usable will external tools.

Under Windows boxes, it will build the new path according to the value of
{shellslash}. Under other systems, the new path will be exclusively composed of
forward slashes. According to {quote-char}, quote characters may be added around
the returned pathname.

For instance, paths like "`c:\Program Files/alongpath/some\ spaces/foo`" will be
changed into: >
    c:\Program Files\alongpath\some spaces\foo   + {quote-char} around
 or c:/Program\ Files/alongpath/some\ spaces/foo + {quote-char} around
according to {shellslash} value.

Internal considerations~
    {quote-char} will value the character:
        1- {a:quote-char} if given,
        2- "" (empty string) otherwise.
    {shellslash} will value the boolean:
        1- {a:shellslash} if given
        2- 'shellslash' if win16, win32, dos16 or dos32
                    and if |SystemDetected()| != "msdos"
        3- 1 if |SystemDetected()| == "unix"
    if {quote-char}=="" && !{shellslash} && |SystemDetected()|=="`msdos`"
        if 'shell' == "`command.com`" => {quote-char} <- ''
        else                        => {quote-char} <- '"'

Note: If you are using "`command.com`" (and not cmd.exe which is available on
MsWindows NT series), you may run into troubles if the {a:pathname} contains

    This mapping opens the current file in MsWindows's files explorer
    [Note: this works if the 'shell' is bash or $COMSPEC]: >
        nmap ,view :exe '!start explorer '.lh#path#fix(expand('%:p'),0)<cr>

Note: Unlike |fnameescape()|, |lh#path#fix()| will work even under the Windows native flavour of gvim, whichever the |'shellslash'| is, and whichever the |'shell'| is.

The code.

" Function: lh#path#fix(pathname [, shellslash [, quote_char ]]) {{{3
" This function was FixEnsurePath from system_tools
function! lh#path#fix(pathname, ...) abort
  " Parameters       {{{4
  " Ignore the last slash or backslash character, if any
  let pathname   = matchstr(a:pathname, '^.*[^/\\]')
  " Default value for the quote character
  let quote_char = ''
  " Determine if 'shellslash' exists (dos-like platforms)
  if lh#os#OnDOSWindows()
    if lh#os#system_detected() == 'msdos'
      let shellslash = 0
      let shellslash = &shellslash
  else "unix
    let shellslash = 1
  " Determine if we will use slashes or backslashes to distinguish directories
  if a:0 >= 1   "
    let shellslash = a:1
    if a:0 >= 2
      let quote_char = a:2

  " Smart definition of quote chars for $COMSPEC
  if (lh#os#system_detected() == 'msdos') && !shellslash && (''==quote_char)
    if (&shell =~ 'command\.com')
      if pathname =~ ' '
        " should also test long directory-names...
        " Best: AVOID command.com !!!
        if &verbose >= 1
          call lh#common#error_msg('lh#path#fix: '.
                \ 'Problem expected because of the space in <'.pathname.'>')
        let quote_char = ''
      let quote_char = '"'

  " Fix the pathname {{{4
  if shellslash
    " return substitute(dname, '\\\([^ ]\|$\)', '/\1', 'g')
    let res = substitute(
          \ substitute(pathname, '\\\([^ ]\|$\)', '/\1', 'g'),
          \ '\(^\|[^\\]\) ', '\1\\ ', 'g')
    " return substitute(
          " \ substitute(pathname, '\([^\\]\) ', '\1\\ ', 'g'),
          " \ '/', '\\', 'g')
    let res = substitute(
          \ substitute(pathname, '\\ ', ' ', 'g'),
          \ '/', '\\', 'g')
  " Note: problem to take care (that explains the complex substition schemes):
  " sometimes the path passed to the function mix the two writtings, e.g.:
  " "c:\Program Files/longpath/some\ spaces/foo"
  " }}}4
  return quote_char . res . quote_char

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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