Bash Script : Check if number starts with - bash

$var=1545334345
The $var is dynamic. How do I check if it starts with 15? I tried:
if [[ $var == 15* ]]; then
echo "Yes"
fi
and
if (( $var -eq 15* )); then
echo "Yes"
fi
Neither works.

Remove the $ from the assignment.
var=1545334345
The first if statement you wrote is correct.
if [[ $var == 15* ]]; then
echo "Yes"
fi

Related

Continue while loop in Bash Script even if a condition fails

#!/bin/bash
var="true"
i=1
while $var
do
read -p "Enter value (true/false): " var
if [[ $var == "true" ]]
then
echo "Iteration : $i"
((i++))
elif [[ $var == "false" ]]
then
echo "Exiting the process"
elif [[ $? -eq 1 ]]
then
echo "Invalid Choice."
echo "Avaialable Choices are true or false"
exit
fi
done
Script is Working Fine. I Enter true the loop will iterate for false the script stops.
I want the script will continue asking "Enter Value" if any other value instead of true or false will be entered.
This would do the same with a more academic syntax:
i=0
while :; do
printf 'Enter value (true/false): '
read -r var
case $var in
true)
i=$((i + 1))
printf 'Iteration : %d\n' $i
;;
false)
printf 'Exiting the process\n'
break
;;
*)
printf 'Invalid Choice.\nAvaialable Choices are true or false\n'
;;
esac
done
You might find this to be a cleaner solution:
i=0
while true; do
read -p "enter value: " myinput
if [[ $myinput = true ]]; then
echo "iteration $i"
i=$((i+1))
elif [[ $myinput = false ]]; then
echo "exiting"
exit
else
echo "invalid input"
fi;
done;
The issue I see with your current code is that it is unclear which command's exit status $? refers to. Does it refer to the echo in the previous elif block? Or the last condition check? Or something else entirely?
I'm new in bash. I tried that:
#!/bin/bash
i=1
while [[ $var != "false" ]]
do
read -p "Enter value (true/false): " var
if [[ $var == "true" ]]
then
echo "Iteration : $i"
((i++))
elif [[ $var == "false" ]]
then
echo "Exiting the process"
elif [[ $? -eq 1 ]]
then
echo "Invalid Choice."
echo "Avaialable Choices are true or false"
fi
done
I changed while $var with while [[ $var ]] because while works like if. It runs the given command. In there it is $var's value.
And I moved exit to first elif expression's end. So if user type false program will exit.

bash check is string contains substring not working

When I execute below script it works fine:
if [[ "[1,2,3]" =~ .*1.* ]]; then
techStatus=1
else
techStatus=0;
fi
echo $techStatus
Output is 1
But when we changes it to variable it does not work.
var1=[1,2,3]
var2=1
if [[ "$var1" =~ .*"$var2".* ]]; then
techStatus=1
else
techStatus=0;
fi
echo $techStatus
Output is 0.
Please help me figure out what is wrong here.
A better & readable approach would be to convert var1 to array and loop through var1.
var1=(1 2 3)
var2=1
for elem in "${var1[#]}"; do
if [[ "$elem" -eq "$var2" ]]; then
techStatus=1
break
else
techStatus=0
fi
done
echo "$techStatus"

existing empty null variable in bash

I am using the code below to determine if a variable in bash exists, if it is empty, or if it has length>0. The code works, but I can't find a good explanation for how if [ -n "${emptyvar+1}" ] can detect if emptyvar is not set. If I remove the +1 then the test fails for "". What is the purpose of the +1 in the test?
#!/bin/bash
emptyvar="a"
if [ -n "${emptyvar+1}" ]
then
echo "emptyvar is defined"
if [[ -z $emptyvar ]]
then
echo "emptyvar is empty";
else
echo "emptyvar is NOT empty";
if [[ -n $emptyvar ]]
then
echo "emptyvar has length > 0";
else
echo "emptyvar has length 0";
fi
fi
else
echo "emptyvar is not defined"
fi
From the bash documentation of Shell Parameter Expansion:
${parameter:+word} If parameter is null or unset, nothing is
substituted, otherwise the expansion of word is substituted.
Omitting the colon (:) makes it test only if the variable is unset, rather than null or unset.
So ${emptyvar+1} tests if $emptyvar is unset. If it is, it expands to the empty string; if not, it expands to 1.
You can also create sets of functions to test a variable passed by its name:
function is_var_set {
[[ -n ${!1+.} ]]
}
function is_var_empty {
[[ -z ${!1} ]]
}
Test:
> A=''
> is_var_set A && echo "A is set." || echo "A is unset."
A is set.
> is_var_empty A && echo "A is empty." || echo "A is not empty."
A is empty.
bash 4.2 added a new test operator, -v, that tests if a variable has been set.
# -v takes the name of the variable, not its values (since you are
# testing if it has a value or not).
if [[ -v emptyvar ]]; then
echo "emptyvar is defined"
if [[ -z $emptyvar ]]
then
echo "emptyvar is empty";
else
echo "emptyvar is NOT empty";
fi
else
echo "emptyvar is not defined"
fi
Note that an empty variable is one whose string has length 0, so your -n test is redundant.
Another way to express it:
$ unset var
$ if [[ -z ${var+x} ]]; then echo unset; elif [[ -z $var ]]; then echo empty; else echo not empty; fi
unset
$ var=
$ if [[ -z ${var+x} ]]; then echo unset; elif [[ -z $var ]]; then echo empty; else echo not empty; fi
empty
$ var=foo
$ if [[ -z ${var+x} ]]; then echo unset; elif [[ -z $var ]]; then echo empty; else echo not empty; fi
not empty
You'll never get "emptyvar has length 0" -- that's what "empty" is

Bash Boolean testing

I am attempting to run a block of code if one flag is set to true and the other is set to false. ie
var1=true
var2=false
if [[ $var1 && ! $var2 ]]; then var2="something"; fi
Since that did not evaluate the way that I expected I wrote several other test cases and I am having a hard time understanding how they are being evaluated.
aa=true
bb=false
cc="python"
if [[ "$aa" ]]; then echo "Test0" ; fi
if [[ "$bb" ]]; then echo "Test0.1" ; fi
if [[ !"$aa" ]]; then echo "Test0.2" ; fi
if [[ ! "$aa" ]]; then echo "Test0.3" ; fi
if [[ "$aa" && ! "$bb" ]]; then echo "Test1" ; fi
if [[ "$aa" && ! "$aa" ]]; then echo "Test2" ; fi
if [[ "$aa" ]] && ! [[ "$bb" ]]; then echo "test3" ; fi
if [[ "$aa" ]] && ! [[ "$cc" ]]; then echo "test4" ; fi
if [[ $aa && ! $bb ]]; then echo "Test5" ; fi
if [[ $aa && ! $aa ]]; then echo "Test6" ; fi
if [[ $aa ]] && ! [[ $bb ]]; then echo "test7" ; fi
if [[ $aa ]] && ! [[ $cc ]]; then echo "test8" ; fi
When I run the preceding codeblock the only output I get is
Test0
Test0.1
Test0.2
however, my expectation is that I would get
Test0
Test1
Test3
Test5
Test7
I have tried to understand the best way to run similar tests, however most examples I have found are set up in the format of
if [[ "$aa" == true ]];
which is not quite what I want to do. So my question is what is the best way to make comparisons like this, and why do several of the test cases that I would expect to pass simply not?
Thank you!
Without any operators, [[ only checks if the variable is empty. If it is, then it is considered false, otherwise it is considered true. The contents of the variables do not matter.
Your understanding of booleans in shell context is incorrect.
var1=true
var2=false
Both the above variables are true since those are non-empty strings.
You could instead make use of arithmetic context:
$ a=1
$ b=0
$ ((a==1 && b==0)) && echo y
y
$ ((a==0 && b==0)) && echo y
$
$ ((a && !(b))) && echo y; # This seems to be analogous to what you were attempting
y
The shell does not have Boolean variables, per se. However, there are commands named true and false whose exit statuses are 0 and 1, respectively, and so can be used similarly to Boolean values.
var1=true
var2=false
if $var1 && ! $var2; then var2="something"; fi
The difference is that instead of testing if var1 is set to a true value, you expand it to the name of a command, which runs and succeeds. Likewise, var2 is expanded to a command name which runs and fails, but because it is prefixed with ! the exit status is inverted to indicate success.
(Note that unlike most programming languages, an exit status of 0 indicates success because while most commands have 1 way to succeed, there are many different ways they could fail, so different non-zero values can be assigned different meanings.)
true and false are evaluated as strings ;)
[[ $var ]] is an equivalent of [[ -n $var ]] that check if $var is empty or not.
Then, no need to quote your variables inside [[. See this reminder.
Finally, here is an explication of the difference between && inside brackets and outside.
The closest you can come seems to be use functions instead of variables because you can use their return status in conditionals.
$ var1() { return 0; }
$ var2() { return 1; } # !0 = failure ~ false
and we can test this way
$ var1 && echo "it's true" || echo "it's false"
it's true
$ var2 && echo "it's true" || echo "it's false"
it's false
or this way
$ if var1; then echo "it's true"; else echo "it's false"; fi
it's true
$ if var2; then echo "it's true"; else echo "it's false"; fi
it's false
Hope this helps.

Bash - why the "0" is not recognized as a number?

I found an interesting Bash script that will test if a variable is numeric/integer. I like it, but I do not understand why the "0" is not recognized as a number? I can not ask the author, hi/shi is an anonymous.
#!/bin/bash
n="$1"
echo "Test numeric '$n' "
if ((n)) 2>/dev/null; then
n=$((n))
echo "Yes: $n"
else
echo "No: $n"
fi
Thank you!
UPDATE - Apr 27, 2012.
This is my final code (short version):
#!/bin/bash
ANSWER=0
DEFAULT=5
INDEX=86
read -p 'Not choosing / Wrong typing is equivalent to default (#5): ' ANSWER;
shopt -s extglob
if [[ $ANSWER == ?(-)+([0-9]) ]]
then ANSWER=$((ANSWER));
else ANSWER=$DEFAULT;
fi
if [ $ANSWER -lt 1 ] || [ $ANSWER -gt $INDEX ]
then ANSWER=$DEFAULT;
fi
It doesn't test if it is a numeric/integer. It tests if n evaluates to true or false, if 0 it is false, else (numeric or other character string) it is true.
use pattern matching to test:
if [[ $n == *[^0-9]* ]]; then echo "not numeric"; else echo numeric; fi
That won't match a negative integer though, and it will falsely match an empty string as numeric. For a more precise pattern, enable the shell's extended globbing:
shopt -s extglob
if [[ $n == ?(-)+([0-9]) ]]; then echo numeric; else echo "not numeric"; fi
And to match a fractional number
[[ $n == #(?(-)+([0-9])?(.*(0-9))|?(-)*([0-9]).+([0-9])) ]]

Resources