I run the following shell command:
nvim +CheckHealth +'w ~/Desktop/file.txt' +qall
This calls nvim
(Neovim) and tells it to run three commands in succession:
CheckHealth
to verify common errors. It runs in a buffer.w ~/Desktop/file.txt
to save that same buffer to a file.qall
to close all buffers.
I’m trying to run this from ruby, using system
. If I run it as a single argument, it works fine:
system("nvim +CheckHealth +'w ~/Desktop/file.txt' +qall")
However, it fails (it runs but does not output a file) if ran as multiple arguments:
system("nvim", "+CheckHealth", "+'w ~/Desktop/file.txt'", "+qall")
What am I doing wrong? Note I am not asking for workarounds. I have a workaround, which is to run it as a single argument. My question is why doesn’t it work when ran as multiple arguments? What am I misunderstanding about system
?
When you use the single argument version of
system
:You're launching a shell and handing it that whole string:
to execute. That means that everything in that string will be interpreted by the shell; in particular, the shell will be handling the single quotes in
+'w ~/Desktop/file.txt'
and by the time vim gets to parse its argument list, it sees three arguments that look like this:+CheckHealth
+w ~/Desktop/file.txt
+qall
In the multi-argument version of
system
:no shell will be launched (a good thing as you don't have to worry about shell command injection and escaping) so the single quotes in the
+w
argument won't be removed by the shell. That means that vim sees these arguments:+CheckHealth
+'w ~/Desktop/file.txt'
+qall
Presumably vim isn't happy with the single quotes in the second argument.
Executive summary:
The single argument version of
system
uses a shell to parse the command line, the multi-argument version doesn't use a shell at all.The single quotes in
+'w ~/Desktop/file.txt'
are there to keep the shell from treating that as two arguments, they're not there for vim.If you're using the multi-argument version of
system
(which you should be doing), then you'd say:and not have to worry about quoting and escaping things to get past the shell.