Hello UNIX & Linux Forums community! Long time Linux daily user hobbyist, new to shell scripting....
I'm working on a script that does all the "work" in one script, and makes calls to a second script to display info to the user via mostly expanding variables in heredocs.
I'm contemplating a -q --quiet option to stop the info displaying. Being new to this, I've thought through and tested the following.
However, I'm at a loss as to the terminology used for what I'm trying to do. That leaves me at a loss to find out if my method would be considered bad scripting, and if so, what would be a more appropriate method to easily implement a --quiet option.
The scripts are quite tested and working well at this point. This is more of an afterthought and mental exercise than something really needed.
BTW, I'm manually parsing options without using getopts. I could post the scripts, around 300 lines total, if needed. It's a (current version) bash script, running Arch Linux if it matters. (mostly current version prog's)
#!/bin/bash
mainfunc () {
echo "run mainfunc commands"
$switch
}
optfunc () {
echo "run user info extras"
}
normal () { switch=optfunc
}
quiet () { switch=
}
while :; do
case "${1}" in
-R) normal ; mainfunc ;;
-Rq) quiet ; mainfunc ;;
*) break
esac
shift
done
Why aren't you using getopts ? Having consistent methods of parsing options greatly contributes to the ability of users unfamiliar with your code automatically know how to get a quick view of the syntax of your utility (with something like: utility -? ), the ability to specify options separately or combined and in any order:
should all produce the same results. And, you should have a built-in help/usage message if an unknown option is found. Instead, your code silently ignores unknown options (leading users to believe that the options they provided were correct when, instead, nothing will be done by your code).
You generally want to set flags while processing options, not run the functions that the options indicate should be run (after you have determined all of hte options that are present).
Your code seems to indicate that the -R option in your utility must always be present. Why have an option if it is always required to be set?
I can think of two methods of implementing a quiet mode. First, use redirections.
if [ "${quietmode}" = "yes" ]
then
exec >/dev/null
fi
printf "this will not be printed in quiet mode\n"
printf "this is a required message and will be printed\n" > /dev/tty
Alternatively:
if [ "${quietmode}" = "yes" ]
then
exec 3>/dev/null
else
exec 3>&1
fi
printf "This won't be printed in quiet mode\n" >&3
printf "This will always be printed\n"
The other way is to use a function:
function myprint() {
local mode=$1
shift
if [ "${mode}" = normal ] && [ "${quietmode}" = "yes" ]
then
return
fi
printf "$@"
}
myprint normal "this will not be printed in quiet mode\n"
myprint quiet "this will be printed always\n"
Second time someone asked why not using getopts. I have not looked into it so far, although I probably should.
With manually parsing options, I consider each argument as an operation rather than an option. No real option ability...
When the program is called with no operations, or a non existent op, they get this or in the former, without the error message.:
$ aurt -qR
Input Error: Please try again or see aurt --help
|=====================================================================================|
| Aurt, a tiny AUR helper script. USAGE: $ aurt [operation] [package] |
|-------------------------------------------------------------------------------------|
| -S Install Update -F Files Provided By Pkg NOTES: |
| -Sv Update By Version -s Search For Pkg |
| -Sf Force Install Update -p Pacman Log |
| -R Remove Pkg And Bld Dir -h Help leafpad-aurt: lat |
| -C Ck All Pkgs For Updates thunar-base dir: tbd |
| -D Package Dependency Details Orphans: R $(p -Qtdq) |
|=====================================================================================|
The scripts:
https:bbs.archlinux.org/viewtopic.php?id=232437
I was contemplating using the --quiet "option" with the -S and -Sv operations only, as the rest couldn't use --quiet.
I read getopts will not take long options? My script needs the ability to process package names, ie: aurt -S <package name> That and manually parsing them seemed more straight forward to me when I started, likely because of my inexperience.
At this point, it sounds like I need to get my head around understanding getopts and figure out how to deal with the program names separately?
Just reading the replies from you guys gives my more things to research, test, and think about.
getopt does not prevent you from getting package names. That's not what "long options" means also, long options means double-dash-word options like --quiet.
In addition to what Corona688 already said (although I think he meant getopts instead of getopt ), in your example:
aurt -S <package name>
<package name> is either a -S option option-argument or an aurt operand; not an option. You haven't given us enough information to know which you intended in your example. The getopts utility does not place any length limit on option-argument nor operand strings.
Furthermore with many versions of the Korn shell, the built-in getopts utility can handle long and short options (although some ksh man pages fail to document this feature). The method ksh uses doesn't work on bash version 3.2.57. I don't know if it works on bash 4.x version and, you haven't said what version of bash you're using.
There are many schemes / methods / alternatives to help process command line -- CLI -- options. Here are a few. Some take a bit of effort to learn, but they will be time-savers in future work.
I especially like the ones that create man-like pages, and help displays automatically ... cheers, drl
Process command-line (CLI) options, arguments
1) getopts, builtin, bash, ksh, zsh
http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options
Also, search for option processing, including:
http://mywiki.wooledge.org/ComplexOptionParsing
2) perl: many, including libgetopt-euclid-perl, which
creates man page, help automatically
3) getopt, enhanced getopts, part of the util-linux, allows GNU "--"
Examples: /usr/share/doc/util-linux/examples, 2016.03.27
4) argp.sh, wrapper for getopt, creates man and help (text, XML), etc.
Allows mixed options and arguments.
Compiled argp.c -> argp for faster execution.
https://sourceforge.net/projects/argpsh/, 2016.03.27
5) shflags, wrapper for getopt, creates help, allow mixed options
and arguments
https://github.com/kward/shflags, 2016.08.01
6) ksh getopts, enhanced, process GNU "--", creates man, help, etc.
Examples: Learning the Korn Shell, O'Reilly, 2nd, p 380ff
7) zsh zparseopts
man zshmodules, part of zshutil
8) Suggested option names:
http://www.shelldorado.com/goodcoding/cmdargs.html#flagnames