The previous patch made it possible to split multiple commands by
adding newline, but not to split a long single command. The sequence
backslash-newline was being used as if it were a quoted newline
character, rather than completely elided the way the shell does.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
tools/virsh.pod | 4 +++-
tools/virt-admin.pod | 3 ++-
tools/vsh.c | 8 ++++++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 2bf1ee77bb..4057edf3a7 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -41,7 +41,9 @@ The B<virsh> program can be used either to run one
I<COMMAND> by giving the
command and its arguments on the shell command line, or a I<COMMAND_STRING>
which is a single shell argument consisting of multiple I<COMMAND> actions
and their arguments joined with whitespace, and separated by semicolons or
-newlines between commands. Within I<COMMAND_STRING>, virsh understands the
+and their arguments joined with whitespace, and separated by semicolons or
+newlines between commands, and where unquoted backslash-newline pairs are
+elided. Within I<COMMAND_STRING>, virsh understands the
same single, double, and backslash escapes as the shell, although you must
add another layer of shell escaping in creating the single shell argument.
If no command is given in the command line, B<virsh> will then start a minimal
diff --git a/tools/virt-admin.pod b/tools/virt-admin.pod
index b2c9a1db6d..e1513e27e5 100644
--- a/tools/virt-admin.pod
+++ b/tools/virt-admin.pod
@@ -24,7 +24,8 @@ The B<virt-admin> program can be used either to run one
I<COMMAND> by giving the
command and its arguments on the shell command line, or a I<COMMAND_STRING>
which is a single shell argument consisting of multiple I<COMMAND> actions
and their arguments joined with whitespace, and separated by semicolons or
-newlines between commands. Within I<COMMAND_STRING>, virt-admin understands the
+newlines between commands, and where unquoted backslash-newline pairs are
+elided. Within I<COMMAND_STRING>, virt-admin understands the
same single, double, and backslash escapes as the shell, although you must
add another layer of shell escaping in creating the single shell argument.
If no command is given in the command line, B<virt-admin> will then start a
minimal
diff --git a/tools/vsh.c b/tools/vsh.c
index 3d9bec896b..9f29bbc777 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -1659,8 +1659,8 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser,
char **res,
*res = q;
- while (*p && (*p == ' ' || *p == '\t'))
- p++;
+ while (*p && (*p == ' ' || *p == '\t' || (*p == '\\'
&& p[1] == '\n')))
+ p += 1 + (*p == '\\');
if (*p == '\0')
return VSH_TK_END;
@@ -1689,6 +1689,10 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser,
char **res,
if (report)
vshError(ctl, "%s", _("dangling \\"));
return VSH_TK_ERROR;
+ } else if (*p == '\n') {
+ /* Elide backslash-newline entirely */
+ p++;
+ continue;
}
} else if (!single_quote && *p == '"') { /* double quote */
double_quote = !double_quote;
--
2.20.1