Null & empty string comparison in Bash [duplicate] - bash

This question already has answers here:
Test for non-zero length string in Bash: [ -n "$var" ] or [ "$var" ]
(7 answers)
Closed 8 years ago.
I don't set any values for $pass_tc11; so it is returning null while echoing. How to compare it in if clause?
Here is my code. I don't want "Hi" to be printed...
-bash-3.00$ echo $pass_tc11
-bash-3.00$ if [ "pass_tc11" != "" ]; then
> echo "hi"
> fi
hi
-bash-3.00$

First of all, note you are not using the variable correctly:
if [ "pass_tc11" != "" ]; then
# ^
# missing $
Anyway, to check if a variable is empty or not you can use -z --> the string is empty:
if [ ! -z "$pass_tc11" ]; then
echo "hi, I am not empty"
fi
or -n --> the length is non-zero:
if [ -n "$pass_tc11" ]; then
echo "hi, I am not empty"
fi
From man test:
-z STRING
the length of STRING is zero
-n STRING
the length of STRING is nonzero
Samples:
$ [ ! -z "$var" ] && echo "yes"
$
$ var=""
$ [ ! -z "$var" ] && echo "yes"
$
$ var="a"
$ [ ! -z "$var" ] && echo "yes"
yes
$ var="a"
$ [ -n "$var" ] && echo "yes"
yes

fedorqui has a working solution but there is another way to do the same thing.
Chock if a variable is set
#!/bin/bash
amIEmpty='Hello'
# This will be true if the variable has a value
if [ $amIEmpty ]; then
echo 'No, I am not!';
fi
Or to verify that a variable is empty
#!/bin/bash
amIEmpty=''
# This will be true if the variable is empty
if [ ! $amIEmpty ]; then
echo 'Yes I am!';
fi
tldp.org has good documentation about if in bash:
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

Related

What are the "options" using in unix shell?

I write the following shell script and cannot understand how it works.
#!/bin/bash
[ -n $HOME ]
echo $?
[ -z $HOME]
echo $?
Output = 0
1
What is the use of -n and -z options
With -n and -z you can check the length of a variable.
if [ -n "$HOME" ]; then
echo "length of \$HOME ist not zero"
fi
if [ -z "$HOME" ]; then
echo "length of \$HOME is zero"
fi

if [-z $var1 ] && [$var2 == "1" ]; then not working as expected [duplicate]

This question already has answers here:
Getting "command not found" error while comparing two strings in Bash
(4 answers)
Closed 3 years ago.
I'm writing a bash script where i need to combine two conditions with && operator
var1=value
var2=1
if [-z $var1 ] && [$var2=="1"]; then
do something
else
do something else
fi
but it always executes the else part.
My research
google gave me bash conditions like this but its not working for me.
if [condition1] && [condition2]; then
do something
fi
Another method i tried is this but it still completely ignored the true part
if [[-z $var1 ]] && [$var2=="1"]; then
do something
else
do something else
fi
Tried with -a operator like this
if [-z $var1 -a $var2=="1" ]; then
tried nested if
if [-z $var1 ]; then
if [$var2=="1"]; then
do something
fi
else
do something else
fi
So i know i am doing something wrong but my goal is i want to check for any value in $var1 and also want $var2 condition to be true and execute the true part.
UPDATE
i tried this
#! /bin/bash
set -o nounset
#set -o errexit
set -o pipefail
set -o xtrace
var1=pop
var2=1
if test -z "$var1" && test "$var2" -eq 1; then
echo Y1
fi
if [ -z "$var1" ] && [ "$var2" -eq 1 ]; then
echo Y2
fi
and this is the output
root#c847b6423295:/# ./test.sh
+ var1=pop
+ var2=1
+ test -z pop
+ '[' -z pop ']'
root#c847b6423295:/#
What am i doing wrong ?
You want to encode "$var1 is not empty and $var2 is equal to 1", you can do:
if test -z "$var1" && test "$var2" -eq 1; then
echo Y
fi
which is equivalent to:
if [ -z "$var1" ] && [ "$var2" -eq 1 ]; then
echo Y
fi
If you want to compare strings, use a single equals sign:
if test "aaa" = "aaa"; then
echo Y
fi

Nested condition of if-statement in bash [duplicate]

This question already has answers here:
Meaning of "[: too many arguments" error from if [] (square brackets)
(6 answers)
Closed 4 years ago.
I want to check that of two variables both or neither are set. I've tried multiple options, and this is the most clean solution I've come up with:
if [ ! -z $A -a -z $B ] || [ -z $A -a ! -z $B ]; then
#error
fi
#success
When I run the script with both A and B set - it runs fine. But when I run it with A missing I get:
./test.sh: line 3: [: too many arguments
./test.sh: line 3: [: too many arguments
line 3 being the condition statement.
When I run it with B missing, I get:
./test.sh: line 3: [: argument expected
./test.sh: line 3: [: argument expected
Is it my condition that has wrong syntax or am I missing smth else?
You should try to avoid -a; it's non-standard and considered obsolete by the POSIX standard. Since || and && have equal precedence, you need to use { ... } to properly group the individual tests.
(This is in addition to the immediate need to quote your parameter expansions.)
if { [ ! -z "$A" ] && [ -z "$B" ]; } || { [ -z "$A" ] && [ ! -z "$B" ]; }; then
However, a simpler expression might be
if [ -z "$A$B" ] || { [ "$A" ] && [ "$B" ]; }; then
The concatenation of two strings is empty if and only if both strings are also empty.
[ "$A" ] is short for [ -n "$A" ], which is equivalent to [ ! -z "$A" ].
Using bash's [[ ... ]] command, you can write the more natural
if [[ -z $A && -n $B || -n $A && -z $B ]];
Quotes are optional in this case, and || and && are usable inside [[ ... ]] with the precedence you expect.
Quote your variables:
if [ ! -z "$A" -a -z "$B" ] || [ -z "$A" -a ! -z "$B" ]; then
If the variables are unquoted and unset, they are replaced with nothing, meaning that the command essentially becomes:
if [ ! -z -a -z ] || [ -z -a ! -z ]; then
resulting in the error you see.
You forgot to use quotation marks around your vars:
if [ ! -z "$A" -a -z "$B" ] || [ -z "$A" -a ! -z "$B" ]; then
echo "error"
fi
Bash will replace your vars in your script with the values, so when A=5 and B is unset, your version will read:
if [ ! -z 5 -a -z ] || [ -z 5 -a ! -z ]; then
You see that the syntax is wrong, as -z expects an argument. When using quotes, is reads:
if [ ! -z "5" -a -z "" ] || [ -z "5" -a ! -z "" ]; then
AS you can see, now the argument for B is an empty string, which is valid.
Also your version would have failed when setting A="string with spaces" when unquoted.

Bash string starting with ">" [duplicate]

This question already has answers here:
In Bash, how can I check if a string begins with some value?
(13 answers)
Closed 6 years ago.
I need to check if a word is starting with ">" character or not
for example A=">abcd" should return true, B="assdf" should not.
I Tried the following snippets but it does not work
if [ "$A" == "\>*" ]; then
echo "True"
fi
The following does not work also
A=">dfssdfsd"
if [[ "$A" =~ "\>*" ]]; then
echo "aaa"
fi
Thank you
You can use the following :
expr "$A" : '>'
$ if [ 0 -ne $(expr 'test' : '>') ]; then echo "True"; else echo "False"; fi
False
$ if [ 0 -ne $(expr '>test' : '>') ]; then echo "True"; else echo "False"; fi
True

Why are the bash -n and -z test operators not inverses for $#

function wtf() {
echo "\$*='$*'"
echo "\$#='$#'"
echo "\$#='"$#"'"
echo "\$#='""$#""'"
if [ -n "$*" ]; then echo " [ -n \$* ]"; else echo "![ -n \$* ]"; fi
if [ -z "$*" ]; then echo " [ -z \$* ]"; else echo "![ -z \$* ]"; fi
if [ -n "$#" ]; then echo " [ -n \$# ]"; else echo "![ -n \$# ]"; fi
if [ -z "$#" ]; then echo " [ -z \$# ]"; else echo "![ -z \$# ]"; fi
}
wtf
produces
$*=''
$#=''
$#=''
$#=''
![ -n $* ]
[ -z $* ]
[ -n $# ]
[ -z $# ]
though it seems to me that [-n $#] should be false because 7.3 Other Comparison Operators indicates that [ -n "$X" ] should be the inverse of [ -z "$X" ] for all $X.
-z
string is null, that is, has zero length
String='' # Zero-length ("null") string variable.
if [ -z "$String" ]
then
echo "\$String is null."
else
echo "\$String is NOT null."
fi # $String is null.
-n
string is not null.
The -n test requires that the string be quoted within the test brackets. Using an unquoted string with ! -z, or even just the unquoted string alone within test brackets (see Example 7-6) normally works, however, this is an unsafe practice. Always quote a tested string. [1]
I know $# is special but I did not know it was special enough to violate boolean negation. What is happening here?
$ bash -version | head -1
GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.0)
The actual numeric exit codes are all 1 or 0 as per
$ [ -n "$#" ]; echo "$?"
0
When $# is empty, "$#" doesn't expand to an empty string; it is removed altogether. So your test is not
[ -n "" ]
but rather
[ -n ]
Now -n isn't an operator, but just a non-empty string, which always tests as true.
"$#" doesn't do what you expect. It's not a different form of "$*", it expands to the quoted list of arguments passed to the current script.
If there are no arguments, it expands to nothing. If there are two arguments a and b c, then it expands to "a" "b c" (i.e. it preserves whitespace in arguments) while "$*" expands to "a b c" and $* would expand to a b c (three words).

Resources