mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
virsh: Elide backslash-newline in batch mode
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>
This commit is contained in:
parent
fe1b683fd0
commit
5817dec014
@ -414,6 +414,9 @@ mymain(void)
|
|||||||
/* Tests of multiple commands. */
|
/* Tests of multiple commands. */
|
||||||
DO_TEST(36, "a\nb\n", " echo a; echo b;");
|
DO_TEST(36, "a\nb\n", " echo a; echo b;");
|
||||||
DO_TEST(37, "a\nb\n", "\necho a\n echo b\n");
|
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
|
# undef DO_TEST
|
||||||
|
|
||||||
|
@ -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>
|
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
|
which is a single shell argument consisting of multiple I<COMMAND> actions
|
||||||
and their arguments joined with whitespace and separated by semicolons or
|
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
|
same single, double, and backslash escapes as the shell, although you must
|
||||||
add another layer of shell escaping in creating the single shell argument.
|
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
|
If no command is given in the command line, B<virsh> will then start a minimal
|
||||||
|
@ -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>
|
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
|
which is a single shell argument consisting of multiple I<COMMAND> actions
|
||||||
and their arguments joined with whitespace and separated by semicolons or
|
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
|
same single, double, and backslash escapes as the shell, although you must
|
||||||
add another layer of shell escaping in creating the single shell argument.
|
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
|
If no command is given in the command line, B<virt-admin> will then start a minimal
|
||||||
|
10
tools/vsh.c
10
tools/vsh.c
@ -1659,8 +1659,8 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
|
|||||||
|
|
||||||
*res = q;
|
*res = q;
|
||||||
|
|
||||||
while (*p && (*p == ' ' || *p == '\t'))
|
while (*p == ' ' || *p == '\t' || (*p == '\\' && p[1] == '\n'))
|
||||||
p++;
|
p += 1 + (*p == '\\');
|
||||||
|
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
return VSH_TK_END;
|
return VSH_TK_END;
|
||||||
@ -1681,7 +1681,7 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
|
|||||||
continue;
|
continue;
|
||||||
} else if (!single_quote && *p == '\\') { /* escape */
|
} 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.
|
* but a \ in '' is not an escaper.
|
||||||
*/
|
*/
|
||||||
p++;
|
p++;
|
||||||
@ -1689,6 +1689,10 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res,
|
|||||||
if (report)
|
if (report)
|
||||||
vshError(ctl, "%s", _("dangling \\"));
|
vshError(ctl, "%s", _("dangling \\"));
|
||||||
return VSH_TK_ERROR;
|
return VSH_TK_ERROR;
|
||||||
|
} else if (*p == '\n') {
|
||||||
|
/* Elide backslash-newline entirely */
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
} else if (!single_quote && *p == '"') { /* double quote */
|
} else if (!single_quote && *p == '"') { /* double quote */
|
||||||
double_quote = !double_quote;
|
double_quote = !double_quote;
|
||||||
|
Loading…
Reference in New Issue
Block a user