Skip to content

[question] should "printf -v%s x" print "-vx" ? #766

@avih

Description

@avih

This is more of a question to the Austin group, but it does apply to ksh93[u+m] as well, and I am hoping the experienced people here would be able to help.

The question at the title is an example case to demonstrate an issue, and the more general question is:

Is the form printf -- "$format" ... portable, in the sense than a conformant implementation is required to support it?

And even more generically:
Is a utility in the "Shell and Utilities" section required to accept -- as "end of options" (unless explicitly stated otherwise) even when the utility has no options (like printf), i.e. that the options section of that utility spec looks like:

OPTIONS:
    None.

So far, as far as I can tell and interpret the spec, the answer is that utilities should accept -- as "end of options" even when the utility has no options (unless stated otherwise).

From Base-definitions, "12.2 Utility Syntax Guidelines" (which include the specification for --):

Some of the standard utilities do not conform to all of these guidelines; in those cases, the OPTIONS sections describe the deviations.

Which I interpret as "The standard utilities shall conform to these guidelines, unless stated otherwise at the OPTIONS section".

And indeed, for some utilities (echo, test, :) it's stated explicitly, e.g. for test:

OPTIONS:
    The test utility shall not recognize the "--" argument in the manner
    specified by Guideline 10 in XBD 12.2 Utility Syntax Guidelines .
    In addition, when the utility name used is [ the utility does not
    conform to Guidelines 1 and 2.

    No options shall be supported.

The counter argument which was raised at the #ksh irc channel on libera - on whether printf is required to support -- is, and I'm quoting:

it does not matter that what the "Utility Syntax Guidelines" says; if it is not explicitly specified, it is not required

Which likely draws from the fact that the docs for utilities which do accept options typically (always?) state that it shall conform with the syntax guidelines, for instance for date:

OPTIONS
    The date utility shall conform to XBD 12.2 Utility Syntax Guidelines .

    The following option shall be supported:

    -u
        Perform operations .....

Some data points, without claiming it proves anything:

  • Of the 24 variations of printf which I tested, all of them accept -- as "end of options". Most of the variants are builtin implementations of shells (bash, ksh93[u+m], zsh (eh...), dash, free/net bsd sh, busybox ash, Schily posix Bourne sh variants, yash, and few more) with and without posix compatibility options where available, but also system /usr/bin/printf on linux, illumos, and even 1981 BSD 2.11 on PDP11. Bare none, all support -- as "end of options".
  • If a conformant printf is not required to accept -- as "end of options", then I think it must print -vx for printf -v%s x, at which case, of the 24 printf variations which I tested, only 4 are conformant with this specific input and indeed print -vx (netbsd sh, busybox ash, zsh, and gnu /bin/printf). All the others (including BSD 2.11) error on invalid option.
  • With other standard utilities (which don't take options) it's less unanimous. For instance basename -- foo/bar prints bar on most systems, but on illumos it prints --. or echo | dd -- bs=1 works on linux and illumos, but on freebsd and openbsd it prints dd: unknown operand --.

So, are standard utilities which have "OPTIONS: None." required to support -- as "end of options"? or not?

Should printf?

(for printf specifically there's a general solution which doesn't work with other utilities: replace a leading - at the format with \055 which is its equivalent octal literal in ASCII, and don't use --. but preferably printf -- "$fmt"... is portable...)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions