printf: '*' broken in conversion spec field width and precision (e.g., "%.*s") GNU bash, version 4.0.23(1)-release (i386-redhat-linux-gnu) on Fedora 11 (additional configuration info appears at the bottom of the page) The printf builtin is broken in many variations of use of '*' (e.g., "%.*s") in a printf conversion spec to set field width and precision from argument values. The following (bash builtin) command returns an empty line. E.g.: $ printf "%.*s\n" 5 "Sample string" $ Compare to correct behavior of printf(1) (/usr/bin/printf) with same args $ /usr/bin/printf "%.*s\n" 5 "Sample string" Sampl $ The builtin works only with either "*.*" or "m.m", (where m is an int), but not with any of the following legal usages: ".*", "*.", "m.*", "*.m", which are all legal variations. I haven't checked the positional "*m$" variants. Although I encountered this working with strings, the same problem exists for specifiers other than 's'. See "Other examples", below. The builtin should work as defined for printf(1) and printf(3) (plus of course its own added features defined in bash(1)). Defined Behavior (man pages, printf(3) gives the most complete picture): bash(1): [in section SHELL BUILTIN COMMANDS, printf] "printf [-v var] format [arguments]" "The format is a character string which contains ... format specifications, each of which causes printing of the next successive argument. In addition to the standard printf(1) formats, ..." [no relevant format specifier detail provided] printf(1): "Interpreted sequences are: ... "and all C format specifications ending with one of diouxXfeEgGcs, ... "Variable widths are handled." printf(3): [in section "Format of the format string""] "Each conversion specification is introduced by the character %, and ends with a conversion specifier. In between there may be (in this order) zero or more flags, an _optional_ minimum field width, an _optional_ precision and an optional length modifier." [in section "The precision"]: "An optional precision, in the form of a period ('.') followed by an optional decimal digit string. "Instead of a decimal digit string one may write "*" or "*m$" (for some decimal integer m) to specify that the precision is given in the next argument, or in the m-th argument, ... "This gives the ... the maximum number of characters to be printed from a string for s and S conversions. [in section "The conversion specifier, s"]: "If a precision is specified, no more bytes than the number specified are written, ... Other examples: Other specifiers (f shown here) seem to share the bug: $ printf "%*.*f\n" 8 2 123.4567890 # "*.*" OK 123.46 $ printf "%8.*f\n" 2 123.4567890 # "m.*" Broken 123 Configuration info: running Fedora 11 with all available updates installed $ bash --version GNU bash, version 4.0.23(1)-release (i386-redhat-linux-gnu) $ uname -a Linux [hostname masked for privacy].net 2.6.30.10-105.2.23.fc11.i686.PAE #1 SMP Thu Feb 11 07:05:37 UTC 2010 i686 athlon i386 GNU/Linux $ sudo lshw [hostname masked for privacy].net description: Desktop Computer product: GA-MA78GM-US2H vendor: Gigabyte Technology Co., Ltd. width: 32 bits capabilities: smbios-2.4 dmi-2.4 smp-1.4 smp configuration: boot=normal chassis=desktop cpus=2 uuid=30303234-[masked for privacy] *-core description: Motherboard product: GA-MA78GM-US2H vendor: Gigabyte Technology Co., Ltd. physical id: 0 version: x.x *-firmware description: BIOS vendor: Award Software International, Inc. physical id: 0 version: F3 (03/11/2009) size: 128KiB capacity: 960KiB capabilities: isa pci pnp apm upgrade shadowing cdboot bootselect socketedrom edd int13floppy360 int13floppy1200 int13floppy720 int13floppy2880 int5printscreen int9keyboard int14serial int17printer int10video acpi usb agp ls120boot zipboot biosbootspecification *-cpu:0 description: CPU product: AMD Athlon(tm) 7750 Dual-Core Processor vendor: Advanced Micro Devices [AMD] physical id: 4 bus info: cpu@0 version: 15.2.3 slot: Socket M2 size: 1350MHz capacity: 3GHz width: 64 bits clock: 200MHz ... [more output available if needed]