cmd: change suppress newline in echo command

By default the echo command emits its arguments followed by a line feed.

If any of the arguments contains the sub-string "\c", the line feed is
suppressed.

This does not match shells used in Linux and BSD where the first argument
has to be -n to suppress the line feed.

The hush shell interferes with the parsing of backslashes. E.g. in the
following command line quadruple backslashes are required for suppressing
the line feed:

for i in 1 2 3; do for j in 4 5; do echo \\\\c ${i}${j}; done; echo; done;

To avoid unexpected behavior the patch changes echo to use -n as first
argument to suppress the line feed.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Heinrich Schuchardt 2021-01-20 12:13:30 +01:00
parent de702493c4
commit d018734c0c

View File

@ -10,47 +10,34 @@
static int do_echo(struct cmd_tbl *cmdtp, int flag, int argc, static int do_echo(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
{ {
int i; int i = 1;
int putnl = 1; bool space = false;
bool newline = true;
for (i = 1; i < argc; i++) { if (argc > 1) {
char *p = argv[i]; if (!strcmp(argv[1], "-n")) {
char *nls; /* new-line suppression */ newline = false;
++i;
if (i > 1)
putc(' ');
nls = strstr(p, "\\c");
if (nls) {
char *prenls = p;
putnl = 0;
/*
* be paranoid and guess that someone might
* say \c more than once
*/
while (nls) {
*nls = '\0';
puts(prenls);
*nls = '\\';
prenls = nls + 2;
nls = strstr(prenls, "\\c");
}
puts(prenls);
} else {
puts(p);
} }
} }
if (putnl) for (; i < argc; ++i) {
if (space) {
putc(' ');
}
puts(argv[i]);
space = true;
}
if (newline)
putc('\n'); putc('\n');
return 0; return 0;
} }
U_BOOT_CMD( U_BOOT_CMD(
echo, CONFIG_SYS_MAXARGS, 1, do_echo, echo, CONFIG_SYS_MAXARGS, 1, do_echo,
"echo args to console", "echo args to console",
"[args..]\n" "[-n] [args..]\n"
" - echo args to console; \\c suppresses newline" " - echo args to console; -n suppresses newline"
); );