Argument checking in bash - shell

I am trying to check the arguments that are passed into the script. It should have a minimum of 2 arguments and can have a maximum of 3. The 3rd argument if present should be "-I". I though I could do this but its not working.
if [ \( ! $# = 2 \) -o \( $# = 3 -a "$3" != "-I" \) ];then
exit 0
fi
What am I doing wrong? Any suggestions on how to make it work?

In bash, you can do something like this:
#!/bin/bash
if [[ $# -eq 3 ]] ; then
if "$3" != "-I ]] ; then
echo "Argument 3 must be '-I' if present"
exit
fi
fi
if [[ $# -ne 2 && $# -ne 3 ]] ; then
echo "Needs two or three arguments"
exit
fi
echo "[$1]"
echo "[$2]"
echo "[$3]"

Try this
#!/bin/bash
MAX_ARGUMENTS=3
echo $#
if [ $# -eq $MAX_ARGUMENTS ]
then
echo "hi"
last=${!#}
if [ $last == "-l" ]
then
echo "its l"
else
echo "its not l"
fi
else
echo "bye"
fi

Related

Check parameters of script in bash

I wanna write a script which check variables of this script.
I have tried some, but it isn't working. The idea is:
If on of the parameters is a number, print that it is number
If on of the parameters is a character, print that it is character
If 'man parameter' is executable, print that it is might be a function
Script I have tried:
#!/bin/bash
echo Hello $LOGNAME'!'
test $# -eq 0 && echo 'Try again, no parameters were entered' || echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in $*
do
if ![["$i" =~ $re]];then
echo 'Parameter '$i' is alphabetical'
else
if [["$i" =~ $re]];then
echo 'Parameter '$i' is digital'
else
if [ $i];then
echo $i' might be a function. Try to use man of --help'
fi
fi
fi
done
#!/bin/bash
echo "Hello ${LOGNAME}!"
[ "$#" -eq 0 ] && { echo 'Try again, no parameters were entered'; exit 1; }
echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in "$#"
do
if ! [[ "$i" =~ $re ]];then
echo "Parameter '$i' is alphabetical"
man "$i" > /dev/null 2> /dev/null
if [ "$?" -eq 0 ];then
echo "$i might be a function. Try to use man of --help"
fi
else
echo "Parameter '$i' is digital"
fi
done;
When you write a test you need spaces around your brackets.
You can easily find and fix those bugs if you use shellcheck

Bash function always ignores the else block

When I run the below code with exact two arguments, the else block doesn't get executed.
If I take out the if else block out of the function, everything works fine.
#!/bin/bash
usage() {
if [[ $# -gt 2 || $# -lt 2 ]]; then
echo "insufficient args"
else
if [[ $# -eq 2 ]]; then
echo "continuing with the script"
fi
fi
}
usage
In this situation, the function usage is receiving 0 arguments from the call.
Change the call to usage $#, which will pass the command line arguments to the usage function.
#!/bin/bash
usage() {
if [[ $# -gt 2 || $# -lt 2 ]]; then
echo "insufficient args"
else
if [[ $# -eq 2 ]]; then
echo "continuing with the script"
fi
fi
}
usage "$#"

Creating a for loop for all regular files and another loop to find # of lines, words, and characters

#!/bin/bash
key="$1"
if [[ $# > 1 ]]; then
echo "true"
if [[ -d $key ]]; then
echo "true"
else
echo "false" >&2
exit
fi
else
echo "false" >&2
exit
fi
loop( for i in \`find . -name "*$1" -print\`)
You should start your script with set -x to better understand what's happening.
set -x
#!/bin/bash
key="$1"
if [[ $# > 1 ]]; then
echo "true"
if [[ -d $key ]]; then
echo "true"
else
echo "false" >&2
exit
fi
else
echo "false" >&2
exit
fi
for i in `find . -name "*$1" -print`
do
wc $i
done
Hope this help, even though your goals remain unclear.

why does not it enter into arg1 if condion, though arg1 is commandline argument

if [ "$#" -ne 1 ]; then
flag=1;
elif ! [[ "$1" == "arg1" || "$1" == "arg2" || "$1" == "arg3" || ...... ]]; then
echo "Invalid"
flag=1;
fi
if [ "$flag" == "1" ]; then
echo "Usage of script...."
exit
fi
count="$(ls *.mov | wc -l)"
if [[ "$count" -eq 0 ]]
then
echo there are 0 .mov files in this path
elif [[ "$count" -eq 1 ]]
then
echo there is 1 .mov file in this path
vlc *.mov
elif [[ $1 = "arg1" ]] ; then
echo entered the tough part....coz its not entering`enter code here`
elif [[ "$1" == "arg2" ]] || [[ "$1" == "arg10" ]] ; then
echo entered here atleast...but not entering
else
script continues
The code does not enter elif conditions involving command line arguments. Tried =, ==, -eq, double square braces, single square braces. But it does not enter, pls help
you should add a disclaimer at the head of the script: " #!/bin/bash"
I tried your script and it does get into the elif.
the code I used is:
if [ "$#" -ne 1 ]; then
echo "not 1 arg"
flag=1;
elif ! [[ "$1" == "arg1" || "$1" == "arg2" || "$1" == "arg3" ]]; then
echo "Invalid"
flag=1;
else
echo "else"
fi
and the input/output are:
$ . script.sh 1 2
not 1 arg
$ . script.sh 1
Invalid
$ . script.sh arg1
else
I tried the second part and it is also working:
count=$2
if [[ "$count" -eq 0 ]] ;then
echo "there are 0 .mov files in this path"
elif [[ "$count" -eq 1 ]] ;then
echo "there is 1 .mov file in this path"
vlc *.mov
elif [[ $1 = "arg1" ]] ; then
echo "arg1 "
elif [[ "$1" == "arg2" ]] || [[ "$1" == "arg10" ]] ; then
echo "arg2 or arg10 "
else
echo "else"
fi
and tested it (second argument is "count"):
$ . script.sh arg1 0
there are 0 .mov files in this path
$ . script.sh 1 0
there are 0 .mov files in this path
$ . script.sh arg10 0
there are 0 .mov files in this path
$ . script.sh arg1 1
there is 1 .mov file in this path
The program 'vlc' is currently not installed. To run 'vlc' please ask your administrator to install the package 'vlc-nox'
$ . script.sh arg10 1
there is 1 .mov file in this path
The program 'vlc' is currently not installed. To run 'vlc' please ask your administrator to install the package 'vlc-nox'
$ . script.sh 1 1
there is 1 .mov file in this path
The program 'vlc' is currently not installed. To run 'vlc' please ask your administrator to install the package 'vlc-nox'
$ . script.sh arg1 2
arg1
$ . script.sh 1 2
else
$ . script.sh arg10 2
arg2 or arg10
You should look into the bash case statement http://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Choices_.28case_and_select.29
For this particular script, it will make your script easier to read and your branching problem will most likely go away..
if your purpose is to handle the arguments passed to the script by command line it's better to use the getopts bash
this is just an example that you can adapt to your scope:
#!/bin/bash
function usage {
echo "usage: ..."
}
while getopts f:o:h opt; do
case $opt in
f)
fileName=$OPTARG
echo "filename[$fileName]"
;;
o)
otherargs=$OPTARG
echo "otherargs[$otherargs]"
;;
h)
usage && exit 0
;;
?)
usage && exit 2
;;
esac
done
~
output
[myShell] ➤ ./n -h
usage: ...
[myShell] ➤ ./n -f myfilename
filename[myfilename]
[myShell] ➤ ./n -o other
otherargs[other]
[myShell] ➤ ./n -l
./n: illegal option -- l
usage: ...

Shell script avoiding that 2 options can be used at the same time

I'm writing a shell script
it works great, the only problem I have is that I want to avoid the possibility of using both options -d) and -x) at the same time when executing my command with my parameters in directories.
Could this be possible with a minimal change in my code?
#!/bin/bash
dir=$1
if [ $# -lt 1 ] ; then
echo "ERROR: no argument"
exit 1 # pas 0
else
case $2
in
-d)
mv $dir/ /tmp/
echo 'moving with -d'
;;
-x)
for f in "$dir"/*; do [[ -x $f ]] && mv "$f" /tmp; done
echo 'moving executables'
;;
*)
mv $dir/* /tmp/
echo 'no flag passed so moving all'
echo "mv $dir/* /tmp/"
;;
esac
fi
I would do it the other way: first extract options, then "if" it.
#!/bin/bash
dir=$1
shift
while [ $# -gt 0 ] ; do
case $1
in
-d)
D_OPTION_SELECTED=1
;;
-x)
X_OPTION_SELECTED=1
;;
esac
shift
done
help() {
echo "Usage $0 dir [-x or -d]";
}
if [[ "$dir" == "" ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 && $X_OPTION_SELECTED -gt 0 ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 ]]; then echo D selected; fi
if [[ $X_OPTION_SELECTED -gt 0 ]]; then echo X selected; fi
But please remember that the good rule is to allow options at first places. So the better version would be:
#!/bin/bash
while [ $# -gt 0 ] ; do
case $1
in
-d)
D_OPTION_SELECTED=1
;;
-x)
X_OPTION_SELECTED=1
;;
*)
dir=$1
;;
esac
shift
done
help() {
echo "Usage $0 [-x or -d] dir";
}
if [[ "$dir" == "" ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 && $X_OPTION_SELECTED -gt 0 ]]; then help; exit 1; fi
if [[ $D_OPTION_SELECTED -gt 0 ]]; then echo D selected; fi
if [[ $X_OPTION_SELECTED -gt 0 ]]; then echo X selected; fi
echo dir=$dir

Resources