Shell – Is it a bug that zsh print the full string with printf ‘%.s’

printfshellzsh

The command printf '%.0s-' `seq 1 30`; echo works fine in all shells tested:

/bin/jsh        : ------------------------------
/bin/attsh      : ------------------------------
/bin/y2sh       : ------------------------------
/bin/ash        : ------------------------------
/bin/dash       : ------------------------------
/bin/b203sh     : ------------------------------
/bin/b43sh      : ------------------------------
/bin/b44sh      : ------------------------------
/bin/bash       : ------------------------------
/bin/ksh        : ------------------------------
/bin/ksh93      : ------------------------------
/bin/lksh       : ------------------------------
/bin/mksh       : ------------------------------
/bin/zsh        : ------------------------------
/bin/zsh4       : ------------------------------

Except for jsh (heirloom shell), y2sh Yet another shell, version 2.39 and lksh (Legacy Korn shell) all other implement a printf builtin:

/bin/attsh      : printf is a shell builtin
/bin/ash        : printf is a shell builtin
/bin/dash       : printf is a shell builtin
/bin/b203sh     : printf is a shell builtin
/bin/b43sh      : printf is a shell builtin
/bin/b44sh      : printf is a shell builtin
/bin/bash       : printf is a shell builtin
/bin/ksh        : printf is a shell builtin
/bin/ksh93      : printf is a shell builtin
/bin/mksh       : printf is a shell builtin
/bin/zsh        : printf is a shell builtin
/bin/zsh4       : printf is a shell builtin

But this line: printf '%.s-' `seq 1 30`; echo makes (only) zsh fail:

/bin/attsh      : ------------------------------
/bin/ash        : ------------------------------
/bin/dash       : ------------------------------
/bin/b203sh     : ------------------------------
/bin/b43sh      : ------------------------------
/bin/b44sh      : ------------------------------
/bin/bash       : ------------------------------
/bin/ksh        : ------------------------------
/bin/ksh93      : ------------------------------
/bin/mksh       : ------------------------------
/bin/zsh        : 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-
/bin/zsh4       : 1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-

The POSIX spec states that:

The precision shall take the form of a ( '.' ) followed by a decimal digit string; a null digit string is treated as zero.

Even if the s format specification states (in the same link):

If the precision is omitted from the argument, it shall be taken to be infinite, so all bytes up to the end of the string shall be written.

It could be reasonable argued that a "missing" precision digit is not "omitted" but has been set to a "null" and therefore should be interpreted as zero.

It would follow that zsh has a bug here.

Is that the correct explanation?

Best Answer

Yes it is a bug (38306). The fix was released in Zsh 5.3.

Source: https://github.com/zsh-users/zsh/commit/e1c745a0dca56afb9cfcace1ef59449152290188