3

I'm writing (or trying to write) a little program in POSIX sh (following the warnings of ShellCheck).
I am especially concerned with a WARNING regarding a loop which in POSIX would be wrong given the double brackets.

Could you tell me what the POSIX sh version of this code is:

 while (( "$#" )); do
    case "$1" in
      [...]
    esac
    shift
 done
Giuseppe
  • 141
  • 5

1 Answers1

13

The POSIX-compliant way to write this condition is

while [ "$#" -gt 0 ]; do

As jesse_b says, if you’re analysing flags, you might want to use getopts (which is defined by POSIX) instead.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • 1
    I know "getopts" works great for just parsing options, but it starts to crumble if you want to support long options or mix positional options and arguments together. – Giuseppe Dec 17 '20 at 15:13
  • @Stephane Why did you add those double quotes? – Vlastimil Burián Dec 17 '20 at 15:16
  • 3
    @LinuxSecurityFreak See part of [this answer](https://unix.stackexchange.com/a/171347/116858) for an explanation why this may be necessary. – Kusalananda Dec 17 '20 at 15:27
  • @Kusalananda Hello K, I just thought in the case of `$#` it seems rather optional as ShellCheck ignores it, good to know. Thanks. – Vlastimil Burián Dec 17 '20 at 15:40
  • 2
    @LinuxSecurityFreak ShellCheck _assumes_ that all shells clears `IFS` or that `IFS` doesn't contain digits. I'd consider this a buglet in ShellCheck. – Kusalananda Dec 17 '20 at 15:43
  • @Giuseppe POSIX `getopts` does not support long options, but modern shells support long options via `getopts` in a unified way that has been originally been implemented in `getopt(3)` on Solaris. `bash` does not support long options because it uses it's own version of `getopt(3)`. See the Bourne Shell man page http://schilytools.sourceforge.net/man/man1/bosh.1.html (approx. page 48) for a documentation on how long options work. Note that this also works with ksh93 the same way. – schily Jan 31 '21 at 14:08