7

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?

  • 2
    I'd say "bug". "Precision" refers to both the . and the optional digit string; an omitted precision looks like to %s, not %.s. – chepner Aug 11 '16 at 1:00
8

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

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

  • Great sleuthing; it's worth noting that the fix isn't in the officially released v5.2, however, so as of this writing the latest official release doesn't have the fix yet. – mklement0 Aug 11 '16 at 18:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy