• [ksh] Warning: pipe symbol within ${} should be quoted?

    From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Thu May 8 01:00:40 2025
    From Newsgroup: comp.unix.shell

    With syntax-check ('ksh -n') I get a warning in Ksh for this expression

    "${pipe#* | }"

    concerning the pipe symbol. (Bash and Zsh don't complain.)

    (2709)$ ksh -n -c '"${pipe#* | }"'
    ksh: warning: line 1: | within ${} should be quoted
    (2710)$ ksh -n -c '"${pipe#* [|] }"'
    ksh: warning: line 1: | within ${} should be quoted
    (2711)$ ksh -n -c '"${pipe#* \| }"'

    (2712)$ bash -n -c '"${pipe#* | }"'
    (2713)$ bash -n -c '"${pipe#* [|] }"'
    (2714)$ bash -n -c '"${pipe#* \| }"'

    (2715)$ zsh -n -c '"${pipe#* | }"'
    (2716)$ zsh -n -c '"${pipe#* [|] }"'
    (2717)$ zsh -n -c '"${pipe#* \| }"'

    Just a bug, or is ksh too sensible here, or some potential subtle issue?

    Janis
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Martijn Dekker@martijn@inlv.demon.nl to comp.unix.shell on Fri May 30 20:52:48 2025
    From Newsgroup: comp.unix.shell

    Op 08-05-2025 om 00:00 schreef Janis Papanagnou:
    With syntax-check ('ksh -n') I get a warning in Ksh for this expression

    "${pipe#* | }"

    concerning the pipe symbol. (Bash and Zsh don't complain.)

    But bash and zsh don't offer linter functionality with -n at all, do they?

    (2709)$ ksh -n -c '"${pipe#* | }"'
    ksh: warning: line 1: | within ${} should be quoted

    ksh -n currently produces the warning in this context for these characters:
    & < > |

    There is nothing in the POSIX shell grammar that suggests these should be quoted there. The string between # and } is a shell pattern, and those are not special characters in POSIX shell patterns.

    While ksh does support extended shell pattern syntax in which & and | may be metacharacters, those characters are not special unless that extended shell pattern syntax is actually used (in which case you don't want to quote them if you want them to be metacharacters). And < and > are never special in patterns at all.

    My conclusion is that this warning is unhelpful. I'll remove it.

    By the way, a little test script shows that old ksh versions had some bugs here:

    pipe="one | two"
    echo "${pipe#* | }"
    pipe="one & two"
    echo "${pipe#* & }"
    pipe="one < two"
    echo "${pipe#* < }"
    pipe="one > two"
    echo "${pipe#* > }"

    Output on ksh 93u+ 2012-08-01, the last "stable" AT&T release:

    | two
    one & two
    two
    two

    Output on ksh 93u+m as of 2022-02-08 (as well as AT&T ksh as of 93v- 2012-08-24 beta):

    two
    two
    two
    two

    I believe the latter is the correct output.
    --
    || modernish -- harness the shell
    || https://github.com/modernish/modernish
    ||
    || KornShell lives!
    || https://github.com/ksh93/ksh
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Sat May 31 00:30:34 2025
    From Newsgroup: comp.unix.shell

    On 30.05.2025 21:52, Martijn Dekker wrote:
    Op 08-05-2025 om 00:00 schreef Janis Papanagnou:
    With syntax-check ('ksh -n') I get a warning in Ksh for this expression

    "${pipe#* | }"

    concerning the pipe symbol. (Bash and Zsh don't complain.)

    But bash and zsh don't offer linter functionality with -n at all, do they?

    I don't know what they internally do when '-n' is provided, but the
    man page (e.g. "man bash") says for the 'set' command (-n/-o noexec)

    -n Read commands but do not execute them. This may be used
    to check a shell script for syntax errors. This is ignored
    by interactive shells.

    which appears to be the same as what's written in the Ksh man page
    (and in POSIX), and I suppose a similar thing valid for Zsh.


    (2709)$ ksh -n -c '"${pipe#* | }"'
    ksh: warning: line 1: | within ${} should be quoted

    ksh -n currently produces the warning in this context for these characters:
    & < > |

    There is nothing in the POSIX shell grammar that suggests these should
    be quoted there. The string between # and } is a shell pattern, and
    those are not special characters in POSIX shell patterns.

    While ksh does support extended shell pattern syntax in which & and |
    may be metacharacters, those characters are not special unless that
    extended shell pattern syntax is actually used (in which case you don't
    want to quote them if you want them to be metacharacters). And < and >
    are never special in patterns at all.

    Yes, that would also be my view; actually reflecting the intention
    of my post.


    My conclusion is that this warning is unhelpful. I'll remove it.

    Which appears to me to be the right thing to do.


    By the way, a little test script shows that old ksh versions had some
    bugs here:

    pipe="one | two"
    echo "${pipe#* | }"
    pipe="one & two"
    echo "${pipe#* & }"
    pipe="one < two"
    echo "${pipe#* < }"
    pipe="one > two"
    echo "${pipe#* > }"

    Output on ksh 93u+ 2012-08-01, the last "stable" AT&T release:

    | two
    one & two
    two
    two

    Output on ksh 93u+m as of 2022-02-08 (as well as AT&T ksh as of 93v- 2012-08-24 beta):

    two
    two
    two
    two

    I believe the latter is the correct output.

    (I'm not sure this is a question or just meant as an observation.)

    At first glance I'd certainly agree. - My reluctance is only because
    I've not thoroughly examined the behavior; at the moment I haven't
    thought (e.g.) about any [syntactical] consequences of the BRE or ERE
    syntax options that Ksh provides. - But as with Ksh regexps, say,
    @(...|...), a BRE/ERE regexp will also have a syntactical context
    that should determine whether in (e.g.) '${var#...}' meta-characters
    in '...' need escaping or not. - Still, the same consequence applies
    that you stated above ("no escapes if intended as meta-characters"),
    so I think it's fine as you see that and put that.

    Janis

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Eric Pozharski@apple.universe@posteo.net to comp.unix.shell on Sat May 31 19:15:08 2025
    From Newsgroup: comp.unix.shell

    with <101dbii$n5nn$1@dont-email.me> Janis Papanagnou wrote:
    On 30.05.2025 21:52, Martijn Dekker wrote:
    Op 08-05-2025 om 00:00 schreef Janis Papanagnou:

    With syntax-check ('ksh -n') I get a warning in Ksh for this expression
    "${pipe#* | }"
    concerning the pipe symbol. (Bash and Zsh don't complain.)
    But bash and zsh don't offer linter functionality with -n at all, do they?
    I don't know what they internally do when '-n' is provided, but the
    man page (e.g. "man bash") says for the 'set' command (-n/-o noexec)

    -n Read commands but do not execute them. This may be used
    to check a shell script for syntax errors. This is ignored
    by interactive shells.

    which appears to be the same as what's written in the Ksh man page
    (and in POSIX), and I suppose a similar thing valid for Zsh.

    That is correct:

    EXEC (+n, ksh: +n) <D>
    Do execute commands. Without this option, commands are read and
    checked for syntax errors, but not executed. This option cannot
    be turned off in an interactive shell, except when `-n' is
    supplied to the shell at startup.

    Yes, reading zsh.info requires some amount of mental gymnastics (or
    parkour, if I may); and sometimes hurts.

    Also, dash(1):

    -n noexec If not interactive, read commands but do not execute
    them. This is useful for checking the syntax of shell
    scripts.

    Also, surprise-surprise, sh of busybox (which doesn't do manuals like at
    all, because manuals are for suckers(?)) with file like this:

    echo foo
    echo "bar

    complains about "unterminated quted string" and doesn't output anything
    with '-n' present; and outputs 'foo' without it and then complains.

    *CUT* [ 71 lines 3 levels deep]
    --
    Torvalds' goal for Linux is very simple: World Domination
    Stallman's goal for GNU is even simpler: Freedom
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Martijn Dekker@martijn@inlv.demon.nl to comp.unix.shell on Mon Jun 9 02:17:38 2025
    From Newsgroup: comp.unix.shell

    Op 30-05-2025 om 23:30 schreef Janis Papanagnou:
    On 30.05.2025 21:52, Martijn Dekker wrote:
    Op 08-05-2025 om 00:00 schreef Janis Papanagnou:
    With syntax-check ('ksh -n') I get a warning in Ksh for this expression

    "${pipe#* | }"

    concerning the pipe symbol. (Bash and Zsh don't complain.)

    But bash and zsh don't offer linter functionality with -n at all, do they?

    I don't know what they internally do when '-n' is provided, but the
    man page (e.g. "man bash") says for the 'set' command (-n/-o noexec)

    -n Read commands but do not execute them. This may be used
    to check a shell script for syntax errors. This is ignored
    by interactive shells.

    which appears to be the same as what's written in the Ksh man page
    (and in POSIX), and I suppose a similar thing valid for Zsh.

    Yes, they all check for syntax errors, but (AFAIK) ksh93 is the only shell that goes beyond that and also provides warnings for things that are not syntax errors -- anything from deprecated syntax like backtick command substitutions, to the performance of $((x)) vs $(($x)).
    --
    || modernish -- harness the shell
    || https://github.com/modernish/modernish
    ||
    || KornShell lives!
    || https://github.com/ksh93/ksh
    --- Synchronet 3.21b-Linux NewsLink 1.2