diff mbox series

[2/6] printf: Support \e in "echo" and "printf" builtins.

Message ID 20180907083414.14673-3-andrew.shadura@collabora.co.uk (mailing list archive)
State Rejected
Delegated to: Herbert Xu
Headers show
Series [1/6] exec: Don't execute binary files if execve() returned ENOEXEC. | expand

Commit Message

Andrej Shadura Sept. 7, 2018, 8:34 a.m. UTC
From: Adam Borowski <kilobyte@angband.pl>

dash's builtin version of printf doesn't support '\e' (escape), and literaly
outputs the 2 characters as-is. As is well known, this sequence is useful,
for example, when outputting ANSI escape sequences.

While it seems that POSIX does not require that printf support '\e',
it is still worth implementing '\e' support, as a way to make the environment
more consistent and avoid this small issue when porting scripts from certain
other systems or when migrating from bash to dash.

Signed-off-by: Adam Borowski <kilobyte@angband.pl>
[reworded the patch description]
Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
Bug-Debian: http://bugs.debian.org/816295
---
 src/bltin/printf.c | 1 +
 src/dash.1         | 4 ++++
 2 files changed, 5 insertions(+)

Comments

Adam Borowski Sept. 11, 2018, 11:22 p.m. UTC | #1
On Fri, Sep 07, 2018 at 10:34:10AM +0200, Andrej Shadura wrote:
> From: Adam Borowski <kilobyte@angband.pl>
> 
> dash's builtin version of printf doesn't support '\e' (escape), and literaly
> outputs the 2 characters as-is. As is well known, this sequence is useful,
> for example, when outputting ANSI escape sequences.
> 
> While it seems that POSIX does not require that printf support '\e',
> it is still worth implementing '\e' support, as a way to make the environment
> more consistent and avoid this small issue when porting scripts from certain
> other systems or when migrating from bash to dash.
> 
> Signed-off-by: Adam Borowski <kilobyte@angband.pl>
> [reworded the patch description]
> Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
> Bug-Debian: http://bugs.debian.org/816295

Note that the patch description is lacking (I did not provide one in the
Debian package), let me elaborate.

First, including the patch is somewhat my fault.  \e was discussed before:
https://www.mail-archive.com/dash@vger.kernel.org/msg00881.html with the
patch not taken; when fixing an unrelated problem later in Jan 2017 I looked
at current code base (the Debian package was far behind) and noticed
something that _appeared_ to be \e.  Turns out I did misread that, and in my
excitement uploaded with this patch.

Wrt POSIX: it can't require \e as it believes in an abstract "portable
character set" which doesn't include ESCAPE.  On the other hand, the two
sets in use: ASCII and EBCDIC both have ESCAPE -- both at 27 although
they disagree whether dec or hex.

On the other hand, support for \e is ubiquitous (not listed = I didn't
check):
* Unix C compilers: gcc clang tcc (not MSVC)
* scripting languages: perl python ruby lua php
* other shells: bash mksh sash posh ksh busybox zsh
* Debian/Ubuntu/Mint/Devuan/Raspbian/... dash

Most remarkably, /bin/sh is dash on Debian derivatives (ie, with this patch)
and something else elsewhere (bash, mksh, ksh or busybox).  Thus, scripts do
expect \e to be supported.

> ---
>  src/bltin/printf.c | 1 +
>  src/dash.1         | 4 ++++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/src/bltin/printf.c b/src/bltin/printf.c
> index 7785735..9b878da 100644
> --- a/src/bltin/printf.c
> +++ b/src/bltin/printf.c
> @@ -340,6 +340,7 @@ conv_escape(char *str, int *conv_ch)
>  	case '\\':	value = '\\';	break;	/* backslash */
>  	case 'a':	value = '\a';	break;	/* alert */
>  	case 'b':	value = '\b';	break;	/* backspace */
> +	case 'e':	value = '\e';	break;  /* escape */
>  	case 'f':	value = '\f';	break;	/* form-feed */
>  	case 'n':	value = '\n';	break;	/* newline */
>  	case 'r':	value = '\r';	break;	/* carriage-return */
> diff --git a/src/dash.1 b/src/dash.1
> index 32f6ac0..b286f79 100644
> --- a/src/dash.1
> +++ b/src/dash.1
> @@ -1201,6 +1201,8 @@ Subsequent output is suppressed.  This is normally used at the end of the
>  last argument to suppress the trailing newline that
>  .Ic echo
>  would otherwise output.
> +.It Li \ee
> +Outputs an escape character (ESC).
>  .It Li \ef
>  Output a form feed.
>  .It Li \en
> @@ -1570,6 +1572,8 @@ The characters and their meanings are as follows:
>  Write a \*[Lt]bell\*[Gt] character.
>  .It Cm \eb
>  Write a \*[Lt]backspace\*[Gt] character.
> +.It Cm \ee
> +Write an \*[Lt]escape\*[Gt] (ESC) character.
>  .It Cm \ef
>  Write a \*[Lt]form-feed\*[Gt] character.
>  .It Cm \en
> -- 
> 2.17.1


Meow!
diff mbox series

Patch

diff --git a/src/bltin/printf.c b/src/bltin/printf.c
index 7785735..9b878da 100644
--- a/src/bltin/printf.c
+++ b/src/bltin/printf.c
@@ -340,6 +340,7 @@  conv_escape(char *str, int *conv_ch)
 	case '\\':	value = '\\';	break;	/* backslash */
 	case 'a':	value = '\a';	break;	/* alert */
 	case 'b':	value = '\b';	break;	/* backspace */
+	case 'e':	value = '\e';	break;  /* escape */
 	case 'f':	value = '\f';	break;	/* form-feed */
 	case 'n':	value = '\n';	break;	/* newline */
 	case 'r':	value = '\r';	break;	/* carriage-return */
diff --git a/src/dash.1 b/src/dash.1
index 32f6ac0..b286f79 100644
--- a/src/dash.1
+++ b/src/dash.1
@@ -1201,6 +1201,8 @@  Subsequent output is suppressed.  This is normally used at the end of the
 last argument to suppress the trailing newline that
 .Ic echo
 would otherwise output.
+.It Li \ee
+Outputs an escape character (ESC).
 .It Li \ef
 Output a form feed.
 .It Li \en
@@ -1570,6 +1572,8 @@  The characters and their meanings are as follows:
 Write a \*[Lt]bell\*[Gt] character.
 .It Cm \eb
 Write a \*[Lt]backspace\*[Gt] character.
+.It Cm \ee
+Write an \*[Lt]escape\*[Gt] (ESC) character.
 .It Cm \ef
 Write a \*[Lt]form-feed\*[Gt] character.
 .It Cm \en