I want to test the number of arguments passed to a Linux shell script. If the number of arguments is not 2 or 4, it should print something. Unfortunately it does not work. Can anyone explain what I am doing wrong?
#!/bin/bash
if [[ $# -ne 2 ]] || [[ $# -ne 4 ]];
then
echo "here";
fi
You should replace logical OR by logical AND, so :
#!/bin/bash
if [[ $# -ne 2 && $# -ne 4 ]]; then
echo "here"
fi
In arithmetic form:
#!/bin/bash
if (($# != 2 && $# != 4)); then
echo "here"
fi
As you can see, no need to use 2 [[ ]]
Logic.
if [[ $# -ne 2 ]] && [[ $# -ne 4 ]]; then
echo "here"
fi
Related
I had written a help menu for reference about the usage of a shell script my_script.sh
echo $'\n\n'
echo $(printf '=%.0s' {1..100})
printf ' %.0s' {1..40}
echo "Welcome"
echo $(printf '=%.0s' {1..100})
echo $'\n'
arg=$1
echo "Input : $arg"
echo
if [[ arg -eq "-h" ]] || [[ arg -eq "-H" ]] || [[ arg -eq "-help" ]] || [[ arg -eq "-Help" ]] || [[ arg -eq "--h" ]] || [[ arg -eq "--H" ]] || [[ arg -eq "--help" ]] || [[ arg -eq "--Help" ]]; then
echo "Help menu requested...."
echo $'\n\n'
echo $(printf '~%.0s' {1..100})
printf ' %.0s' {1..43}
echo "Help Menu"
echo $(printf '~%.0s' {1..100})
echo $'\n'
exit 0
else
echo "Executing a program...."
./another_script.sh
fi
When I execute `myscript.sh -h' (or any of the '-' prefixed option), it goes to the if condition, but any other argument doesn't. What am I doing wrong here? I'm new to bash scripts.
Two simple problems with your if:
-eq is for integer comparison, = or == for strings
Use $arg in your if (instead of arg).
But: I would recommend using getopts instead of string comparison. This would make the part more robust, taking care of different ordering of parameters, or when one letter parameters are combined into a single argument.
Unfortunately I do not know the exact reason why your code does not work, but I can offer you a quick fix: You can write "==" instead of "-eq" and prefix your variable "arg" with a dollar sign. Then your script should work fine.
Working example (GNU bash 4.4.19):
arg=$1
if [[ $arg == "-h" ]] || [[ $arg == "-H" ]]; then
echo "Help!"
else
echo "Stop!"
fi
the -eq operation is only used for comparing numbers.
To compare strings uses the operation =
You forgot $ sign for variables arg in Bash, should be $arg
When we use variables in Bash, we should better use double quote.
use #() for multiple strings comparison.
so the if conditions [[ arg -eq "-h" ]] should be [[ "$arg" = "-h" ]]
When comparing a variable with multiple strings, we can use [[ "$arg" = #(-h|-H|--help|--HELP|--h|--H|-help|--HELP) ]].
if [[ "$arg" = #(-h|-H|--help|--HELP|--h|--H|-help|--HELP) ]]; then
echo "Help menu requested...."
echo $'\n\n'
echo $(printf '~%.0s' {1..100})
printf ' %.0s' {1..43}
echo "Help Menu"
echo $(printf '~%.0s' {1..100})
echo $'\n'
exit 0
else
echo "Executing a program...."
./another_script.sh
fi
In addition, we can use boxes(boxes - Command line ASCII boxes unlimited!
) to generate a comment box
cat <<EOF | boxes -a c -d shell -p a5 -s 30x9
HELP MENU
bla bla
EOF
output:
########################################
# #
# #
# HELP MENU #
# #
# bla bla #
# #
# #
########################################
In the following code I want to compare the command line arguments with the parameters but I am not sure what is the current syntax to compare the arguments with parameters..i.e "==" or "-eq".
#!/bin/bash
argLength=$#
#echo "arg = $1"
if [ argLength==0 ]; then
#Running for the very first
#Get the connected device ids and save it in an array
N=0
CONNECTED_DEVICES=$(adb devices | grep -o '\b[A-Za-z0-9]\{8,\}\b'|sed -n '2,$p')
NO_OF_DEVICES=$(echo "$CONNECTED_DEVICES" | wc -l)
for CONNECTED_DEVICE in $CONNECTED_DEVICES ; do
DEVICE_IDS[$N]="$CONNECTED_DEVICE"
echo "DEVICE_IDS[$N]= $CONNECTED_DEVICE"
let "N= $N + 1"
done
for SEND_DEVICE_ID in ${DEVICE_IDS[#]} ; do
callCloneBuildInstall $SEND_DEVICE_ID
done
elif [ "$1" -eq -b ]; then
if [ $5 -eq pass ]; then
DEVICE_ID=$3
./MonkeyTests.sh -d $DEVICE_ID
else
sleep 1h
callCloneBuildInstall $SEND_DEVICE_ID
fi
elif [ "$1" -eq -m ]; then
echo "Check for CloneBuildInstall"
if [ "$5" -eq pass ]; then
DEVICE_ID=$3
callCloneBuildInstall $SEND_DEVICE_ID
else
echo "call CloneBuildInstall"
# Zip log file and save it with deviceId
callCloneBuildInstall $SEND_DEVICE_ID
fi
fi
function callCloneBuildInstall {
./CloneBuildInstall.sh -d $SEND_DEVICE_ID
}
From help test:
[...]
STRING1 = STRING2
True if the strings are equal.
[...]
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
-lt, -le, -gt, or -ge.
But in any case, each part of the condition is a separate argument to [.
if [ "$arg" -eq 0 ]; then
if [ "$arg" = 0 ]; then
Why not use something like
if [ "$#" -ne 0 ]; then # number of args should not be zero
echo "USAGE: "
fi
When/how to use “==” or “-eq” operator in test?
To put it simply use == when doing lexical comparisons a.k.a string comparisons but use -eq when having numerical comparisons.
Other forms of -eq (equal) are -ne (not equal), -gt (greater than), -ge (greater than or equal), -lt (lesser than), and -le (lesser than or equal).
Some may also suggest preferring (( )).
Examples:
[[ $string == "something else" ]]
[[ $string != "something else" ]] # (negated)
[[ $num -eq 1 ]]
[[ $num -ge 2 ]]
(( $num == 1 ))
(( $num >= 1 ))
And always use [[ ]] over [ ] when you're in Bash since the former skips unnecessary expansions not related to conditional expressions like word splitting and pathname expansion.
I received an assignment in school where I'm suppose to generate output in a random color if specified. My program doesn't generate the color that I would like it to when the RANDOM option is selected.
My input to the program is:
echoc RANDOM|colour string
And my code looks like:
declare -A colours=(
[black]="0;30" [red]="0;31" [green]="0;32" [yellow]="0;33" [blue]="0;34" [magenta]="0;35" [cyan]="0;36" [white]="0;37"
[BLACK]="1;30" [RED]="1;31" [GREEN]="1;32" [YELLOW]="1;33" [BLUE]="1;34" [MAGENTA]="1;35" [CYAN]="1;36" [WHITE]="1;37")
if [ $# -lt 2 ]; then
echo "Usage: echoc COLOUR|RANDOM STRING"
exit 1
fi
regex='^red$|^green$|^yellow$|^blue$|^magenta$|^cyan$|^white|^black$'
shopt -s nocasematch
if [[ $1 =~ $regex ]]; then
printf '\033[%sm' ${colours[$1]}
shift
printf '%s\033[0m\n' "$*"
exit 0
elif [[ $1 == "RANDOM" ]]; then
printf '\033[%sm' ${colours[$((RANDOM%8+1))]}
shift
printf '%s\033[0m\n' "$*"
exit 3
else
echo COLOUR must be one of 'red|green|yellow|blue|magenta|cyan|white|RANDOM'
exit 2
fi
declare -A colours=(
[1]="0;30" [2]="0;31" [3]="0;32" [4]="0;33" [5]="0;34" [6]="0;35" [7]="0;36" [8]="0;37"
[black]="0;30" [red]="0;31" [green]="0;32" [yellow]="0;33" [blue]="0;34" [magenta]="0;35" [cyan]="0;36" [white]="0;37"
[BLACK]="1;30" [RED]="1;31" [GREEN]="1;32" [YELLOW]="1;33" [BLUE]="1;34" [MAGENTA]="1;35" [CYAN]="1;36" [WHITE]="1;37")
if [ $# -lt 2 ]; then
echo "Usage: echoc COLOUR|RANDOM STRING"
exit 1
fi
regex='^red$|^green$|^yellow$|^blue$|^magenta$|^cyan$|^white|^black$'
shopt -s nocasematch
if [[ $1 =~ $regex ]]; then
printf '\033[%sm' ${colours[$1]}
shift
printf '%s\033[0m\n' "$*"
exit 0
elif [[ $1 == "RANDOM" ]]; then
derp=$(($RANDOM%8+1))
printf '\033[%sm' ${colours["$derp"]}
shift
printf '%s\033[0m\n' "$*"
exit 3
else
echo COLOUR must be one of 'red|green|yellow|blue|magenta|cyan|white|RANDOM'
exit 2
fi
My code is as below:
if [[ $? -eq 0 ]]; then
$command1;
$command2;
$command3;
fi
Can I have a one liner to do the same? I have this but looking for something better and fancy.
if [[ $? -eq 0 ]]; then $command1;$command2;$command3; fi
Your attempted oneliner works just fine, as in this example:
commnd1='echo foo'
commnd2='echo bar'
commnd3='echo baz'
true
if [[ $? -eq 0 ]];then $commnd1;$commnd2;$commnd3;fi
You can also use && and command grouping:
[[ $? -eq 0 ]] && { cmd1; cmd2; cmd3; }
I need to check two variables, count and count1, for equality with 2.
I tried the following code, but it didn't work:
if [ $count -eq 2 || $count1 -eq 2 ]; then
echo "Condition passsed"
fi
How can I fix it?
That type of conditional doesn't recognize ||. You either need to use -o (or), or use a [[ test:
if [ $count -eq 2 -o $count1 -eq 2 ]; then
echo "Condition passsed"
fi
if [[ $count -eq 2 || $count1 -eq 2 ]]; then
echo "Condition passsed"
fi
You need to use [[:
if [[ $count -eq 2 || $count1 -eq 2 ]]; then echo "Condition passsed"; fi