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

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.

Stephen Kitt
  • 434,908
  • 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 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