Most people use
casestatements for option processing because it's simple and easy and it works. There are countless examples using either built-ingetoptsor/usr/bin/getoptor custom/hand-crafted. It often IS the better method, and certainly better/more-readable than a bunch of if/elif/else statements.POSIX sh does not support regex tests. For that, you need a shell like bash, ksh, or zsh, it's one of the reasons why the
[[ ... ]]built-in was invented - to do stuff that[akatestcan't do without breaking compatibility.Or you could use
awkto do your matching but (like most external programs) it's not something you'd want to fork repeatedly in a shell loop - the advantage of a built-in is that it IS built-in. Or you could useperl, but in that case it would make more sense to just write the entire script in perl.If you're not going to use
nocasematchthen at least usetr '[:upper:]' '[:lower:]'or similar to convert$actionto all lower-case (or upper, it doesn't matter) before trying to match it against something.Then you wouldn't need all those ugly and unreadable and tedious to type & edit bracket expressions just to match mixed-case. That all looks like you're going out of your way to make things harder for yourself when you should be trying to make things easier and simpler. Converting to all lower or all upper case would also benefit matching with a
casestatement as well as regex.BTW, those
[upper:]and[:lower:]classes work with at least GNU and BSDtr, maybe others too. As @Stephane mentions, GNUtrdoesn't support multi-byte characters, sotr A-Z a-zworks too. It's not unreasonable to expect that it, or some other version of tr, will one day work correctly for multi-byte unicode characters. If handling unicode options is important to you, use a unicode-capable tool likeperl(which has a built-inlcfunction for case conversion) to do the case conversion.You should use a heredoc rather than multiple
printfstatements for long sequences of text. It's not like you're actually using any of printf's formatting options (and if needed, you can use heredocs with printf). Also, all that embedded whitespace at the end of each line will annoy users, as it will end up in the selection or clipboard if copied. e.g.cat <<__EOF__ Usage: pocsag [ACTION] [INPUTMETHOD/REDACTION] [OUTPUTMETHOD/PATHTOFILE/SERVICEACTION] Examples: pocsag decode rtlsdr cli pocsag decode netcat file pocsag redact medical ~/media/signals/pocsag/decoded/POCSAG* pocsag service rtlsdr start Actions: decode Envoke the usage of the input tuner, sox and multimon-ng to decode the signals. redact Copy file but redact regex matching lines of a file. For example: Removing medical TXs. service Used to start/stop the systemd service in user's ~/.config. Relies on rtlsdr_pager_rx Input Methods: rtlsdr Use an RTLSDR device plugged into the local computer. netcat Listen to localhost:7355 using netcat, then process and output locally. __EOF__This is more readable, easier to edit, and easier to re-format if/when needed with
fmt,fold,par, or similar. It's just text, with no embedded code.Put your usage message in a function called, e.g.
usage. And same for otheriforcaseclauses with multiple lines of code or long strings of text to print. You don't want to embed lots of text or code in a case statement or a long if/else/elif/then/fi statement - something like that should be readable at a glance without needing to page forwards and backwards just to get an overview of what the entire statement is doing.
cat <<__EOF__
Usage: pocsag [ACTION] [INPUTMETHOD/REDACTION] [OUTPUTMETHOD/PATHTOFILE/SERVICEACTION] Examples:
pocsag decode rtlsdr cli
pocsag decode netcat file
pocsag redact medical ~/media/signals/pocsag/decoded/POCSAG*
pocsag service rtlsdr start
Actions:
decode Envoke the usage of the input tuner, sox and multimon-ng to decode the signals.
redact Copy file but redact regex matching lines of a file. For example: Removing medical TXs.
service Used to start/stop the systemd service in user's ~/.config. Relies on rtlsdr_pager_rx
Input Methods:
rtlsdr Use an RTLSDR device plugged into the local computer.
netcat Listen to localhost:7355 using netcat, then process and output locally.
__EOF__
This is more readable, easier to edit, and easier to re-format if/when needed with fmt, fold, par, or similar. It's just text, with no embedded code.
- Put your usage message in a function called, e.g.
usage. And same for otheriforcaseclauses with multiple lines of code or long strings of text to print. You don't want to embed lots of text or code in a case statement or a long if/else/elif/then/fi statement - something like that should be readable at a glance without needing to page forwards and backwards just to get an overview of what the entire statement is doing.