tag 10782 notabug thanks On 02/10/2012 11:52 AM, Praveen A wrote: > $ printf %04d 12 > 0012$ printf %4d 12 > 12$ printf %04s 12 > 12$ printf %4s 12 > 12$ Thanks for the report. In printf(3), POSIX states the use of the 0 modifier with %s is undefined: http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html "0 For d , i , o , u , x , X , a , A , e , E , f , F , g , and G conversion specifiers.... For other conversions, the behavior is undefined." Note that glibc silently ignores %04x, and gcc correctly warns about it being fishy: $ cat foo.c #include int main() { printf("%04s\n", "hi"); return 0; } $ gcc -o foo foo.c -Wall foo.c: In function ‘main’: foo.c:2:1: warning: '0' flag used with ‘%s’ gnu_printf format [-Wformat] $ ./foo hi > > It would be very useful if it works for strings too (I found this when > trying to zero pad hex values in an ipv6 address). Now it requires an > additional sed find and replace to get the desired result. Note that you didn't even test coreutils - you tested the built-in printf of your shell. Coreutils intentionally errors out on this undefined behavior, to make it obvious that there is no sane documented way to implement it: $ /usr/bin/printf %04s 12 /usr/bin/printf: %04s: invalid conversion specification Implementing %04s in coreutils, but not also in glibc, bash, dash, ksh, and so forth, all at the same time, would just cause user confusion due to the inconsistencies; plus, you would have to wait for those fixes to propagate into your machine before you could rely on it. Rather, you should patch your script to use %d or %x or other tricks in a manner that works today: # Use $(()) to convert hex to decimal, then 0-pad it back out to hex $ printf %04x $((0x12)) 0012 # given an arbitrary string in $1, add 0-padding if needed to extend # it to at least 4 characters $ f() { case ${#1} in 0|1|2|3) printf %0$((4-${#1}))d%s 0 "$1" ;; *) printf %s "$1" ;; esac } $ f 12 0012 As such, I'm closing this bug report as something we won't change. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org