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
Fix the grammer in a nearby comment while at it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
tools/virsh.pod | 4 ++--
tools/virt-admin.pod | 4 ++--
tools/vsh.c | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 67edb57b14..2bf1ee77bb 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -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
diff --git a/tools/virt-admin.pod b/tools/virt-admin.pod
index 3ddbbff934..b2c9a1db6d 100644
--- a/tools/virt-admin.pod
+++ b/tools/virt-admin.pod
@@ -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
diff --git a/tools/vsh.c b/tools/vsh.c
index 610de4495b..3d9bec896b 100644
--- a/tools/vsh.c
+++ b/tools/vsh.c
@@ -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 */
@@ -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++;
--
2.20.1