-1

I am using getopts to parse options. I want to ensure that the optstring has only a single colon at the start, and if this does not exist I want to introduce it.

Here is an example of the initialisation of optstring

  local optstring="sn:z:" 
Dilna
  • 405
  • 1
  • 6
  • There are two parts to the obvious answer, and I suspect they both are already asked and answered elsewhere on this site: Checking whether a string starts with a given prefix, and adding a prefix to a string. Which of those, if either, do you already know how to do? – Charles Duffy May 07 '23 at 14:20
  • 1
    (We expect a question to describe not just a goal, but also exactly how you got stuck in your own effort towards that goal). – Charles Duffy May 07 '23 at 14:20
  • 2
    Why do you need to do this? You're presumably writing the code to initialize `optstring` so why do you need to write other code to check your code? Please [edit] your code to provide a [mcve] that demonstrates the actual problem you're trying to solve as this sounds like an [XY Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Ed Morton May 07 '23 at 14:39
  • 1
    please update the question with the code you've attempted, the (wrong) result generated by your code, and the (correct) expected result – markp-fuso May 07 '23 at 14:40
  • 1
    oddly related https://stackoverflow.com/q/76189223/9072753 – KamilCuk May 07 '23 at 14:40
  • 2
    @KamilCuk not oddly - Veak and Bennings are 2 of the **many** logins used by the same person here and on SE. – Ed Morton May 07 '23 at 14:41
  • I want the `optstring` to change at runtime to go to silent error reporting if the user pass the option `-s`. – Dilna May 07 '23 at 15:15

2 Answers2

1

This POSIX-compatible code (tested with Bash and Dash) handles arbitrary numbers of colons at the start of the string:

optstring=:${optstring#${optstring%%[!:]*}}
  • ${optstring%%[!:]*} expands to the (possibly empty) string of colons at the start of $optstring. It does this by removing the first non-colon character ([!:]) and everything that follows it.
  • ${optstring#${optstring%%[!:]*}} expands to $optstring with all the colons at the start removed.

The transformation can be done in two steps to (possibly) make it more readable:

colons=${optstring%%[!:]*}
optstring=:${optstring#$colons}

Another (also POSIX-compatible) approach is to use a loop to remove leading colons:

while [ "${optstring#:}" != "$optstring" ]; do
    optstring=${optstring#:}
done
optstring=:$optstring
pjh
  • 6,388
  • 2
  • 16
  • 17
  • Whilst this expression is effective, it is hard to read and understand, and would need some hard concentration. – Dilna May 07 '23 at 18:46
0
optstring=:${optstring#:}

First we unconditionally add a colon, then we use a parameter expansion to expand our string with any preexisting colon removed.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    This, however, assumes `optstring` starts with at most one `:`. – chepner May 07 '23 at 14:33
  • 1
    @chepner, indeed. One could `shopt -s extglob` and then use `${opstring#+(:)}` to avoid that limitation. – Charles Duffy May 07 '23 at 16:24
  • Is it good to enable `extglob` in the `.bashrc` ? I have made a library, would the command go into each file individually. Ideally I would like to always allow it. Could there be any conflicts that could break other things ? – Dilna May 07 '23 at 18:39
  • @Bennings, technically setting extglob causes pattern-match behavior to break the standard -- that's why it's off-by-default -- but the behaviors that it changes are ones that a person is unlikely to ever actually want. There are certainly some Linux distros that _do_ enable it by default, so you wouldn't be the first to decide it's more benefit than cost. – Charles Duffy May 08 '23 at 14:48
  • By standard, you mean the POSIX Standard ? You are then claiming of behaviors performed by `extglob` that people do not want ? Is that because much of the existing system code assumes adherence to POSIX, which would break the behavior when `extglob` is enabled across the board ? – Dilna May 08 '23 at 17:47
  • @Bennings, I did not, and do not, claim that extglob does things that people don't want in practice. I _do_ assert that it makes the shell's globbing no longer POSIX-compliant. And it's certainly not true that "much of" system code/tools are incompatible with extglob behavior -- little if any is, but if someone wants a _firm guarantee_ that scripts written assuming POSIX behavior will still conform to the letter of the standard (even if only in circumstances that are extremely unlikely to ever happen in real-world practice), then they need extglob off. – Charles Duffy May 08 '23 at 18:14