dash printf builtin does not honor \xNN to print hexadecimal
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
dash (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
VERSION AND CONTEXT
===================
$ uname -a; lsb_release -a; dash --version; dpkg -s dash
Linux alain-Desktop 3.13.0-63-generic #103-Ubuntu SMP Fri Aug 14 21:42:59 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.3 LTS
Release: 14.04
Codename: trusty
Package: dash
Essential: yes
Status: install ok installed
Priority: required
Section: shells
Installed-Size: 228
Maintainer: Ubuntu Developers <email address hidden>
Architecture: amd64
Version: 0.5.7-4ubuntu1
Depends: debianutils (>= 2.15), dpkg (>= 1.15.0)
Pre-Depends: libc6 (>= 2.14)
Description: POSIX-compliant shell
The Debian Almquist Shell (dash) is a POSIX-compliant shell derived
from ash.
.
Since it executes scripts faster than bash, and has fewer library
dependencies (making it more robust against software or hardware
failures), it is used as the default system shell on Debian systems.
Homepage: http://
Original-
BUG DESCRIPTION AND HOW TO REPRODUCE
=======
Pretty well all is in the title!
Try this in a terminal:
$ bash -c 'printf "\x41\n"'; dash -c 'printf "\x41\n"'; $(which printf) '\x41\n'
A
\x41
A
In case you suspect that comes from expansion in the terminal, you can do the same under dash (type dash in the terminal and do the same line). The result is identical.
Same thing if you have a script:
#! /bin/dash
printf '\x41\n'
printf "\x41\n" # We do both quotes and double quotes in case there is an escaping issue!
This script will display:
\x41
\x41
WHAT IS EXPECTED:
================
Of course what is expected is that dash would display, same as bash and GNU printf:
A
That is what is described in all printf's documentations I could ever read, starting from the ancestor:
#include <stdio.h>
int main(){
printf(
}
Name this file /tmp/test.c, compile it with gcc /tmp/test.c -o /tmp/test
Then run /tmp/test
You will obviously get:
A
SUMMARY:
========
Testing various printfs with the string: "\x41\n"
Produces the expected output (capital letter A followed by line feed) with:
- the C printf
- the bash builtin
- the GNU printf (in /usr/bin)
Produces an un-escaped output with dash!
I am still searching for dash documentation of the builtin printf, but I seriously doubt such an output for printing '\x41' is even POSIX compliant.
INTERSTING NOTE:
===============
We could suspect there would be the same issue when converting numbers from octal... but no, all is fine with octal!
$ bash -c 'printf "\101\n"'; dash -c 'printf "\101\n"'; $(which printf) '\101\n'
A
A
A
In octal, be it bash, dash or the GNU printf all outputs are identical.
In any case someone might consider "it is not a bug, it is a feature" to NOT honour escaping of hexadecimal and honour the octal escaping we can say at least that this "feature" is a lack of consistency in converting numbers to chars with dash!
INTERESTING NOTE2:
=================
I read from the description of dash on the launchpad: (...) 'dash' which is the Debian Almquist Shell (dash) is a POSIX-compliant shell derived from ash.
Well, I did the same test on my (not Ubuntu-related) Synology that is precisely running ash embedded in busybox (not bash, not dash) and doing
printf '\x41\n'
Produces the expected output: A + LF
[Exact version of this 'ash': BusyBox v1.16.1 (2014-02-11 20:12:01 CST) built-in shell (ash) ]
So there might have been some distortion in the derivation from ash!
Well, I made some more research: I think this can be closed as
WON'T FIX
This seem to be a feature (not a bug) to comply exactly to POSIX, **nothing more**.
Here is the related POSIX documentation: www.unix. com/man- page/POSIX/ 1posix/ printf/
http://
It specifies octal escaping, and it also explains that Hexadecimal escaping can be ambiguous (the explanation is far fetched!)
So ash might have added the \x but dash removed it (probably) to be strictly POSIX to the minimum.
Also, we don't have \u or \U escaping for Unicode.
If you need \x, \u or \U, the workaround is to use the GNU printf instead of the builtin.
Sorry for the inconvenience;