]> xenbits.xensource.com Git - libvirt.git/commitdiff
virsh: Treat \n like ; in batch mode
authorEric Blake <eblake@redhat.com>
Thu, 21 Feb 2019 18:36:32 +0000 (12:36 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 26 Feb 2019 20:16:04 +0000 (14:16 -0600)
I wanted to do a demonstration with virsh batch mode, which
takes multiple commands all packed into a single argument:

$ virsh -c test:///default 'echo a; echo b;'
a
b

but that produced a really long line, so I tried to make it
more legible:

$ virsh -c test:///default '
   echo a;
   echo b;
'
error: unknown command: '
'

Let's be more like the shell, and treat unquoted newline as a
command separator just as we do for semicolon.  In fact, with
that, I can even now mix styles:

$ virsh -c test:///default '
   echo a; echo b
   echo c
'
a
b
c

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 7fb701d58080ca276b42495354e5fc13b4acd6b4..bb053cec27bf829784b2fdadcb510c8252b76924 100644 (file)
@@ -411,6 +411,10 @@ mymain(void)
     DO_TEST(34, "hello\n", "echo --str hello");
     DO_TEST(35, "hello\n", "echo --hi");
 
+    /* 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");
+
 # undef DO_TEST
 
     VIR_FREE(custom_uri);
index 67edb57b1499493c512684c0668fde89ae936e21..146cd03e85ec0ab3f34f6c64846fff20b4586297 100644 (file)
@@ -40,8 +40,8 @@ as a name.
 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
-between commands.  Within I<COMMAND_STRING>, virsh understands the
+and their arguments joined with whitespace and separated by semicolons or
+newlines between commands.  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 3ddbbff934ffd4ba625e113b06c0a7e82f475a71..d34f768fbb76d88e781609582fd8b3c3570d786c 100644 (file)
@@ -23,8 +23,8 @@ Where I<command> is one of the commands listed below.
 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
-between commands.  Within I<COMMAND_STRING>, virt-admin understands the
+and their arguments joined with whitespace and separated by semicolons or
+newlines between commands.  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 610de4495b592f067dfeedeb1ee9da5f877cb7f3..823f3c14772760ca7d5d29508a91da07587bb8b5 100644 (file)
@@ -1664,7 +1664,7 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
 
     if (*p == '\0')
         return VSH_TK_END;
-    if (*p == ';') {
+    if (*p == ';' || *p == '\n') {
         parser->pos = ++p;             /* = \0 or begin of next command */
         return VSH_TK_SUBCMD_END;
     }
@@ -1672,7 +1672,7 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
     while (*p) {
         /* end of token is blank space or ';' */
         if (!double_quote && !single_quote &&
-            (*p == ' ' || *p == '\t' || *p == ';'))
+            (*p == ' ' || *p == '\t' || *p == ';' || *p == '\n'))
             break;
 
         if (!double_quote && *p == '\'') { /* single quote */