diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2016-10-18 14:39:08 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2016-10-19 01:39:05 +0200 |
commit | 9706664b8827614817a43f3a4ac4b6ae8463a906 (patch) | |
tree | 9c0288adb64b6779b6e19dfc873f1ba0fe65b16f /runtime/doc | |
parent | 16da3a6fe01de74eaebfd4750dabe27b3b7ab068 (diff) | |
download | rneovim-9706664b8827614817a43f3a4ac4b6ae8463a906.tar.gz rneovim-9706664b8827614817a43f3a4ac4b6ae8463a906.tar.bz2 rneovim-9706664b8827614817a43f3a4ac4b6ae8463a906.zip |
system('foo &', 'bar'): Show error, don't crash.
Closes #3529
Closes #5241
In Vim,
:echo system('cat - &', 'foo')
works because for both system() and :! Vim writes input to a temp file and uses
shell syntax to redirect the file to the backgrounded `cat` (get_cmd_output()
.. make_filter_cmd()).
In Nvim,
:echo system('cat - &', 'foo')
fails because we write the input directly via pipes (shell.c:do_os_system()),
but (per POSIX[1]) backgrounded process input stream is redirected from
/dev/null (unless overridden by shell redirection; supported only by some shells
[2]), so our writes are ignored, the process exits quickly, and if we are
writing data larger than the buffer size we'll see EPIPE.
This still works:
:%w !tee > foo1358.txt &
but this does not:
:%w !tee foo1358.txt &
though it *should* (why doesn't it?) because we still do the temp file dance
in do_bang() .. do_filter().
[1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_03_02
[2] http://unix.stackexchange.com/a/71218
Diffstat (limited to 'runtime/doc')
-rw-r--r-- | runtime/doc/eval.txt | 32 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 8 |
2 files changed, 22 insertions, 18 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index dedbe49605..3c9b4dafcd 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -6838,23 +6838,30 @@ system({cmd} [, {input}]) *system()* *E677* Get the output of the shell command {cmd} as a |string|. {cmd} will be run the same as in |jobstart()|. See |systemlist()| to get the output as a |List|. - - When {input} is given and is a string this string is written - to a file and passed as stdin to the command. The string is - written as-is, you need to take care of using the correct line - separators yourself. - If {input} is given and is a |List| it is written to the file - in a way |writefile()| does with {binary} set to "b" (i.e. - with a newline between each list item with newlines inside - list items converted to NULs). - Pipes are not used. + Not to be used for interactive commands. + + If {input} is a string it is written to a pipe and passed as + stdin to the command. The string is written as-is, line + separators are not changed. + If {input} is a |List| it is written to the pipe as + |writefile()| does with {binary} set to "b" (i.e. with + a newline between each list item, and newlines inside list + items converted to NULs). + *E5677* + Note: system() cannot write to or read from backgrounded ("&") + shell commands, e.g.: > + :echo system("cat - &", "foo")) +< which is equivalent to: > + $ echo foo | bash -c 'cat - &' +< The pipes are disconnected (unless overridden by shell + redirection syntax) before input can reach it. Use + |jobstart()| instead. Note: Use |shellescape()| or |::S| with |expand()| or |fnamemodify()| to escape special characters in a command argument. Newlines in {cmd} may cause the command to fail. The characters in 'shellquote' and 'shellxquote' may also cause trouble. - This is not to be used for interactive commands. The result is a String. Example: > :let files = system("ls " . shellescape(expand('%:h'))) @@ -6869,9 +6876,6 @@ system({cmd} [, {input}]) *system()* *E677* The command executed is constructed using several options when {cmd} is a string: 'shell' 'shellcmdflag' {cmd} - The command will be executed in "cooked" mode, so that a - CTRL-C will interrupt the command (on Unix at least). - The resulting error code can be found in |v:shell_error|. This function will fail in |restricted-mode|. diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 1598beaaa0..bb1f993ab6 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -141,10 +141,10 @@ are always available and may be used simultaneously in separate plugins. The `neovim` pip package must be installed to use Python plugins in Nvim (see |provider-python|). -|:!| and |system()| do not support "interactive" commands; use |:terminal| for -that instead. Terminal Vim supports interactive |:!| and |system()|, but gui -Vim does not. See ":help gui-pty" in Vim: - http://vimdoc.sourceforge.net/htmldoc/gui_x11.html#gui-pty +|:!| does not support "interactive" commands. Use |:terminal| instead. +(GUI Vim has a similar limitation, see ":help gui-pty" in Vim.) + +|system()| does not support writing/reading "backgrounded" commands. |E5677| |mkdir()| behaviour changed: 1. Assuming /tmp/foo does not exist and /tmp can be written to |