Reputation: 19331
I'm working with a legacy shell script that's used for testing certain features in binaries (i.e. calls nm
, objdump
, ldd
, etc; and does some parsing on the results). The shell script currently is very "touchy", and large, so I'd like to minimize changes I make to it.
It currently starts with a check for the number of parameters, each one being a path, i.e.:
if [ "$#" -lt 3 ]
then
echo "Error. Invalid number of arguments."
exit
fi
I would like to add some additional arguments and their long-form equivalents to disable certain features internal to the script, without invalidating the above test, i.e.:
-h | --help: Print shell usage and expected arguments.
-x | --xfer: Do some extra copy logic.
-d | --dry: Do a dry-run, and don't actually change any files.
However, I do not want the flags (i.e. arguments that begin with a hyphen) to be counted as arguments (i.e. doesn't affect the assignment of parameters to $1
, $2
, and $3
). For example, the following is currently a valid invocation of my script:
bash ./test.sh ./ ./out ./logs
I would like the following possible invocations to also work:
bash ./test.sh ./ ./out ./logs --dry
bash ./test.sh --xfer ./ ./out ./logs
bash ./test.sh --help
bash ./test.sh ./ --xfer ./out --dry ./logs
How would I setup a script to "filter out" arguments that begin with hyphens (one or two), and maintain the same assignments to $1
, $2
,and $3
?
Upvotes: 2
Views: 2210
Reputation: 295815
You can modify the argument list after-the-fact:
set -- one two three
Thus, you can put your own parsing up at the top, and use set --
to put whatever arguments you want in place into their desired positions.
Consider as an example of filtering:
#!/usr/bin/env bash
# ^^^^- not /bin/sh, as arrays are bash-only
help_and_exit() {
local retval=${1:-1}
cat <<EOF
${0##*/} [-d|--dry-run] [-x|--xfer] input output whatever
...put your extended help here...
EOF
exit "$retval"
}
args=( )
dry_run=0; xfer=0
while (( $# )); do
case $1 in
-d|--dry) dry_run=1 ;;
-x|--xfer) xfer=1 ;;
-h|--help) help_and_exit 0 ;;
-*) printf 'Unknown option: %q\n\n' "$1"
help_and_exit 1 ;;
*) args+=( "$1" ) ;;
esac
shift
done
set -- "${args[@]}"
Upvotes: 3