]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsh: Elide backslash-newline in batch mode
authorEric Blake <eblake@redhat.com>
Tue, 26 Feb 2019 18:49:25 +0000 (12:49 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 26 Feb 2019 21:42:21 +0000 (15:42 -0600)
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.

Again, add more tests, although this time it seems more like I am
suffering from a leaning-toothpick syndrome with all the \.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
tests/virshtest.c
tools/virsh.pod
tools/virt-admin.pod
tools/vsh.c

index bb053cec27bf829784b2fdadcb510c8252b76924..d77d3d81d49ee51b0bba620fdc4b9899d83bd4dd 100644 (file)
@@ -414,6 +414,9 @@ mymain(void)
     /* Tests of multiple commands.  */
     DO_TEST(36, "a\nb\n", " echo a; echo b;");
     DO_TEST(37, "a\nb\n", "\necho a\n echo b\n");
+    DO_TEST(38, "a\nb\n", "ec\\\nho a\n echo \\\n b;");
+    DO_TEST(39, "a\n b\n", "\"ec\\\nho\" a\n echo \"\\\n b\";");
+    DO_TEST(40, "a\n\\\n b\n", "ec\\\nho a\n echo '\\\n b';");
 
 # undef DO_TEST
 
index 146cd03e85ec0ab3f34f6c64846fff20b4586297..0533fb363fcc60f176a2cbbad397687a8d14488b 100644 (file)
@@ -41,7 +41,8 @@ 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
+newlines between commands, 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
index d34f768fbb76d88e781609582fd8b3c3570d786c..9bbff428469dc6f6a94ac243176172b330400846 100644 (file)
@@ -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, 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
index 823f3c14772760ca7d5d29508a91da07587bb8b5..2fd1564d15865ff8e445e3439b62de2a09b24e97 100644 (file)
@@ -1659,8 +1659,8 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
 
     *res = q;
 
-    while (*p && (*p == ' ' || *p == '\t'))
-        p++;
+    while (*p == ' ' || *p == '\t' || (*p == '\\' && p[1] == '\n'))
+        p += 1 + (*p == '\\');
 
     if (*p == '\0')
         return VSH_TK_END;
@@ -1681,7 +1681,7 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
             continue;
         } else if (!single_quote && *p == '\\') { /* escape */
             /*
-             * The same as the bash, a \ in "" is an escaper,
+             * The same as in shell, a \ in "" is an escaper,
              * but a \ in '' is not an escaper.
              */
             p++;
@@ -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;