CODE: cmd.sh
#!/bin/bash
if [ $# -ne 4 ]; then
echo not 4
exit 1
fi
while [[ $# > 1 ]]
do
key="$1"
case $key in
-f|--file)
FILE="$2"
shift
;;
-t|--type)
TYPE="$2"
shift
;;
--default)
DEFAULT=YES
;;
*)
# unknown option
;;
esac
shift
done
echo FILE = "${FILE}"
echo TYPE = "${TYPE}"
GOAL
How do i ensure that the user always has to enter both file
and type
arguments and ensure that they always enter 2 arguments
, not more and not less.
EDIT
Updated the code above, ne 4 because of the flags.
ONLY VALID RESULT
$ ./cmd.sh -f asd -t def
FILE = asd
TYPE = def
CURRENT ISSUE
1.
$ ./cmd.sh -f asd asd asd
FILE = asd
TYPE =
I didn't include the -t flag but it still considers it as valid.
2.
$ ./cmd.sh -f asd -g asd
FILE = asd
TYPE =
I included an invalid flag but it still considers it as valid.
SOLUTION
#!/bin/bash
if [ $# -ne 4 ]; then
echo not 4
exit 1
fi
while [[ $# > 1 ]]
do
key="$1"
case $key in
-f|--file)
FILE="$2"
shift
;;
-t|--type)
TYPE="$2"
shift
;;
--default)
DEFAULT=YES
;;
*)
echo invalid option $key
exit 1
;;
esac
shift
done
echo FILE = "${FILE}"
echo TYPE = "${TYPE}"
LAST ISSUE
How do i ignore the length requirement and check if they type -h or --help? I want to print out the usage in that case.
MY ATTEMPT
#!/bin/bash
# Ensure that environment variables are not used by accident
FILE=
TYPE=
arg0="$(basename "$0" .sh)"
usage() { echo "Usage: $arg0 -f file -t type" >&2; exit 1; }
error() { echo "$arg0: $*" >&2; usage; }
help() { echo "Help: some help file" >&1; exit 0; }
version() { echo "Version: 1.0" >&1; exit 0; }
while [ $# -gt 1 ]
do
case "$1" in
-h|--help)
help
;;
-v|--version)
version
;;
-f|--file|-t|--type)
;;
-*) error "unrecognized option $1";;
*) error "unexpected non-option argument $1";;
esac
shift
done
[ $# -eq 4 ] || usage
while [ $# -gt 1 ]
do
case "$1" in
-f|--file)
[ -z "$FILE" ] || error "already specified file name $FILE"
[ -z "$2" ] && error "empty file name specified after $1"
FILE="$2"
shift
;;
-t|--type)
[ -z "$TYPE" ] || error "already specified file type $TYPE"
[ -z "$2" ] && error "empty type name specified after $1"
TYPE="$2"
shift
;;
-*) error "unrecognized option $1";;
*) error "unexpected non-option argument $1";;
esac
shift
done
# Should never execute either of these errors
[ -z "$FILE" ] && error "no file name specified"
[ -z "$TYPE" ] && error "no type name specified"
echo FILE = "${FILE}"
echo TYPE = "${TYPE}"
This broke the code and started throwing the following error:
$ bash a2.sh -f typename -t asda
a2: unexpected non-option argument typename
Usage: a2 -f file -t type
The solution below is much more elegant than what i tried to do!
UPDATE - TESTING
$ bash d2.sh -t type -f filename -V
FILE = filename
TYPE = type
$ bash d2.sh -h
d2.sh: no file name specified (and no --default)
Usage: d2 [-d|--default][-h|--help][-V|--version][{-f|--file} file] [{-t|--type} type]
$ bash d2.sh -V
d2.sh: no file name specified (and no --default)
Usage: d2 [-d|--default][-h|--help][-V|--version][{-f|--file} file] [{-t|--type} type]