I am running the below script, but it looks like the $filename or $srvname did not get the input value.
say for eg: ./test.sh -n abcd.net gives the output echo 'Filename or node name must be defined.'
it means that, the $srvname did not get the value "abcd.net", please advise am i doing anything wrong. ?
set -x
usage () {
echo "usage: $0 -n <nodename>"
echo "usage: $0 -f <filename>"
echo "usage: $0 -h <help>"
}
while getopts ":nfh:" opt; do
case "$opt" in
n) srvname="$OPTARG" ;;
f) filename="$OPTARG" ;;
h) # help
usage
exit 0
;;
:) echo "Error: -$OPTARG requires an argument"
usage
exit 1
;;
?) echo "Error: unknown option -$OPTARG"
usage
exit 1
;;
esac
done
function dosomecheck {
echo "do some checks"
}
if [ "$filename" != "" ] ; then
# read file
for x in `cat $filename` ; do
dosomecheck $x
done
fi
if [ "$srvname" != "" ] ; then
# read file
for x in $srvname ; do
dosomecheck $x
done
fi
Thanks in advance
Try doing:
while getopts ":n:f:h" opt;
because -n and -f takes argument while -h doesn't.
Related
I've an question, how to use *if *or *case * statements to do below command :
command.sh --value string ?
I tried :
case "$1" in
[--value ])
echo "You choose value"
;;
*)
echo "plz chs diff one"
;;
esac
But it is not what I want to achieve.
I want to run command.sh --value string , where string is the first argument.
getopts is a tool that can be used to parse arguments
usage() {
echo "Usage: $0 [-v]" 1>&2
}
exit_abnormal() {
usage
exit 1
}
while getopts "v" arg; do
case $arg in
v) USE_VALUE='true' ;;
?)
echo "Invalid option: -${OPTARG}."
echo
usage
;;
esac
done
shift
if [[ $USE_VALUE == "true" ]]; then
...
fi
You can try this:
if [ "$1" = "--value" ]; then
echo "You choose value $2"
else
echo "plz chs diff one"
fi
usage ()
{
echo "USAGE MANUAL"
echo "-u -> displays this usage manual"
echo "-t -> sets EXEC variable to echo"
echo "-t -> sets DEPTH variable to inputed string"
exit 1
}
while getopts ":t:u:d:" o; do
case "${o}" in
t)
EXEC=echo
;;
d)
DEPTH=${OPTARG}
;;
u)
usage
;;
esac
done
shift $((OPTIND-1))
if [ -z "${d}" ] || [ -z "${t}" ]; then
usage
fi
If i get it right if i do this:
./script -d
I have to provide something like:
./script -d full
The question is, how do i restrict what the argument of d can be. Like if someone types ./script -d full or ./script -d empty its gonna change the value of DEPTH to full or empty, but if they put something like ./script -d infinite the script doesnt run and echo somthing like wrong argument provided.
You can use a nested case:
d) case "$OPTARG" in
full|empty) DEPTH=$OPTARG ;;
*) echo 'Invalid depth' >&2 ; exit 1 ;;
esac
;;
I have one problem , when i select one option , for exemple ./test.sh -f it should print "mel" but it reads all code.
How does it enter the if condition and passes with other argument ?
if getopts :f:d:c:v: arg ; then
if [[ "${arg}" == d ]] ; then
d_ID=$OPTARG
eval d_SIZE=\$$OPTIND
else
echo "Option -d argument missing: needs 2 args"
echo "Please enter two args: <arg1> <arg2>"
read d_ID d_SIZE
echo "disc $d_ID $d_SIZE" >> $FILENAME
fi
if [[ "${arg}" == c ]] ; then
c_NOME="$OPTARG"
eval c_ID1=\$$OPTIND
eval c_ID2=\$$OPTINDplus1
eval c_FICHEIRO=\$$OPTINDplus2
else
echo "Option -c argument missing: needs 4 args"
echo "Please enter two args: <arg1> <arg2> <arg3> <agr4>"
read c_NOME c_ID1 c_ID2 c_FICHEIRO
echo "raidvss $c_NOME $c_ID1 $c_ID2 $c_FICHEIRO" >> $FILENAME
fi
if [[ "${arg}" == f ]] ; then
echo "mel"
fi
fi
You are using getopts parameters wrong.
if getopts :f:d:c:v: arg
means that -f will follow the value of parameter, like
-f 5
If you want just have -f (without value) you need to change it to
if getopts :fd:c:v: arg ; then
(I deleted the ':'). Also, I think you should better use while cycle and case statements.
See this example
while getopts fd:c:v: opt
do
case "$opt" in
f) echo "mel";;
d) discFunction "$OPTARG";;
c) otherFunction "$OPTARG";;
v) nop;;
\?) echo "$USAGE" >&2; exit 2;;
esac
done
shift `expr $OPTIND - 1`
what is the easiest, most straight forward, way to use getopts in bash script.
if i have a script called: myscript and it CAN take the the arguments: -p -r -s -x
if argument x then exit
if argument p then echo "port 10"
if argument s then add 2+2
if argument r then echo env
This is a hypothetical script but I would just like to see an example of how this would be done.
while getopts :xpsr opt; do
case $opt in
x ) exit ;;
p ) echo port 10 ;;
s ) (( 2 + 2 )) ;;
r ) echo env ;;
\? ) echo "${0##*/}" [ -xpsr ]; exit 1 ;;
esac
done
usage()
{
echo "Usage: $0 [-o <offset>] [-h];"
exit 0;
}
# -o (offset) need a value
# -h prints help
offset=0 # 0 is default offset
while getopts o:s opt
do
case "$opt" in
d) offset="$OPTARG";; # changing offset
s) usage # calls function "usage"
\?) echo "$OPTARG is an unknown option"
exit 1;; # all other options
esac
done
shift $((OPTIND-1))
FILE_LIST=$1
MOVE=0
while getopts "m" OPT; do
case $OPT in
m) MOVE=1 ;;
M) MOVE=1 ;;
*) echo "Invalid parameter." >&2; exit 1 ;;
esac
done
echo $MOVE
echo $FILE_LIST
I will pass optional argument ( -m/-M) and file list .
test.sh -m a.txt
its display 1 -m , but i am looking for 1 a.txt
Supost if test.sh a.xt
it should be diplsay 0 and a.txt
You need to shift the arguments.
MOVE=0
while getopts "mM" OPT; do
case $OPT in
M|m) MOVE=1
shift;;
*) echo "Invalid parameter." >&2; exit 1 ;;
esac
done
echo $MOVE
FILE_LIST=$1
echo $FILE_LIST
You can also combine m and M into one case.
If I understand right, you want the syntax for running the script to be something like:
./scriptname [-mM] firstfile [secondfile ...]
If this is correct, none of the other answers quite work; here's how I'd do it:
#!/bin/bash
# Parse command options
MOVE=0
while getopts "mM" OPT; do
case "$OPT" in
m|M) MOVE=1 ;;
*) echo "Invalid option." >&2; exit 1 ;;
esac
done
shift $(( OPTIND-1 )) # Remove options from the argument list
# Parse command arguments
if [[ $# -eq 0 ]]; then
echo "No files specified." >&2
exit 1
fi
FILE_LIST=( "$#" ) # Use an array in case of spaces in filenames
# Some examples of things to do with the results:
# Work with the specified files individually:
for FILE in "${FILE_LIST[#]}"; do
chmod g+w "$FILE"
done
# Work with the specified files as a group:
if (( MOVE == 1 )); then
mv "${FILE_LIST[#]}" "$DEST_DIR"
else
cp "${FILE_LIST[#]}" "$DEST_DIR"
fi
I do not exactly know what you want but Here are some code examples:
First example assumes that the filelist is given always after the -m option
while getopts "m:" OPT
do
case $OPT in
m)
echo "option m"
FILE_LIST = $OPTARG
;;
*)
echo "error"
;;
esac
done
echo $FILE_LIST
Or a different approach with a filelist not related to the -m option
while getopts "m:" OPT
do
case $OPT in
m)
echo "option m"
MOVE = 1
;;
*)
echo "error"
;;
esac
done
shift $(($OPTIND - 1))
FILE_LIST = $1
echo $FILE_LIST
Hope this suits your needs
You have to use $OPTARG value for this. Notice m:. The colon specifies that there are arguments passed to -m
#!/bin/bash
MOVE=0
while getopts "m:M:" OPT; do
case $OPT in
m|M) MOVE=1
FILE_LIST="$FILE_LIST $OPTARG"
;;
*) echo "Invalid parameter." >&2; exit 1 ;;
esac
done
shift $(( OPTIND-1 ))
[[ $MOVE != 1 ]] && FILE_LIST=$1
echo $MOVE
echo $FILE_LIST