0

I am writing scripts with the following boilerplate CLI pattern:

usage(){
  echo "$0 yada yada"
  ...
  echo 
}
for arg in "$@"; do
  case "$arg" in
    '--help|-help') set -- "$@" '-h';;
    ...
  esac
done

OPTIND=1
while getopts 'h...' opt; do
  case "$opt" in
     'h') usage; exit 0;;
      ...
  esac
done
shift $((OPTIND-1))

Is there any way to compress or encapsulate this in BASH on linux with other tools, perhaps an additional dependency?

Chris
  • 894
  • 5
  • 18
  • That sounds like a bad approach. If your script were `grep` for instance, `grep -e --help -- --help` is meant to look for `--help` in the file called `--help`, but you would end up transforming that to `grep -e -h -- -h`. Also with the standard CLI interface `cmd -help` is meant to be the same as `cmd -h -e -l -p` (or `cmd -h -e lp` if the `-e` option takes an argument, etc). See [getopt, getopts or manual parsing - what to use when I want to support both short and long options?](https://unix.stackexchange.com/q/62950) and many other Q&As here for approaches at parsing long options – Stéphane Chazelas Jul 25 '23 at 16:45
  • @StéphaneChazelas grep requires commands searching for, for example, '--help' to be escaped, `grep '\-\-help'`, even after adding quotes, so this is beside the point, imo. Yes, there are other ways, this is a simple one and I am looking for an even simpler way. – Chris Jul 25 '23 at 16:55
  • @StéphaneChazelas yes, I am aware of that edge case -- if I define parameters `-h, -e, -l, -p` then a user could eventually stumble on a surprise. I am probably not going to change things for now, since the goal is for the user to stumble on `help`. If the edge case becomes an issue, I'll change it. – Chris Jul 25 '23 at 16:57
  • no. `-` is not a regex operator so putting backslash in front of it yields unspecified behaviour. To `grep` for `--help`, you use either `grep -- --help file` where `--` marks the end of options or `grep -e --help file` or `grep -e--help file` where `--help` is the argument to the `-e` option. – Stéphane Chazelas Jul 25 '23 at 16:57
  • @StéphaneChazelas I have had to escape backslashes with `grep` in cross platform scripts. Surely in some contexts you are right, but it's got nothing to do with my question. In fact, I don't need to use `-- --help` to work with bash if I escape the dashes, and I don't need to use `--regexp` (`-e`) either. – Chris Jul 25 '23 at 16:58
  • You use backslash to escape regexp operators as in `grep '\.' file` to look for a literal `.` or to introduce some other operators, like in `grep '\([[:upper:]]\{4\}\)\1'` to look for a repeated sequence of 4 uppercase letters. `grep '\-\-help'` is just plain wrong even if in most `grep` implementations it will do the same as `grep -e --help`. – Stéphane Chazelas Jul 25 '23 at 17:01
  • @StéphaneChazelas nonetheless, I'll consider your feedback in the boilerplate I'm not sure I can qualify including due to its lack of brevity. – Chris Jul 25 '23 at 17:02
  • @StéphaneChazelas " grep '\-\-help' is **just plain wrong** even if in most grep implementations it will do the same as grep -e --help" -- this feels like a matter of opinion and a rant. Please stop defacing my question. – Chris Jul 25 '23 at 17:03
  • If you use util-linux `getopt` or other option parsing tools/library, then you don't need to worry about all that. It will also properly handle unambiguous long option abbreviation (like `--h` / `--he`) here assuming it's the only long option that starts with `h`/`he`) and `--input=foo` in addition to `--input foo` and `-ifoo` + `-i foo`, etc. – Stéphane Chazelas Jul 25 '23 at 17:04
  • @StéphaneChazelas I'll explore getopt, thanks -- presuming it is not as ubiquitous as the `getopts` built-in – Chris Jul 25 '23 at 17:22

0 Answers0