Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In one of my lab tutorial there was a command to be checked.

test -z $LOGNAME || echo Logname is not defined

when I execute this command the output is "Logname is not defined". Man page for test says

> -z STRING
>               the length of STRING is zero

when I echo $LOGNAME it prints out my login name. So there is a value for $LOGNAME. In the first command above since the right part of the command is executed, it implies the left part has returned false. Why does it return false when $LOGNAME has a value?

share|improve this question

migrated from stackoverflow.com Jun 3 '13 at 9:08

This question came from our site for professional and enthusiast programmers.

1  
There is a big difference between "zero length" and "not defined". STRING='' defines a string of length zero. The -z option to test does not distinguish between undefined or zero length. – William Pursell Jun 3 '13 at 13:30
    
thanx for that info William – DesirePRG Jun 3 '13 at 13:34
up vote 4 down vote accepted

The line

test -z $LOGNAME || echo Logname is not defined

is an OR list, and can be translated as:

DO echo Logname is not defined IF test -z $LOGNAME FAILS

As you mention in your question, test -z $LOGNAME tests whether $LOGNAME is zero length ... and since it isn't, the test fails. Replacing || with && as follows will give you the behaviour you want:

test -z $LOGNAME && echo Logname is not defined

EDIT: As per William Pursell's comment below, test -n (test for a non-zero-length string) and || might make more conceptual sense, but you need to quote $LOGNAME in this case (and in fact it's a good idea to get into the habit of quoting variables in general):

test -n "$LOGNAME" || echo Logname is not defined
share|improve this answer
    
thank you. I was unable to understand what the -z option does before. Now I understood. – DesirePRG Jun 3 '13 at 4:23
    
So the shell would return 1 for failure and 0 for success. which is the opposite compared to other languages?if we think it that way. It is confusing since if the left part is evaluated to 1 the right part doesn't have to be executed – DesirePRG Jun 3 '13 at 4:29
1  
@DesirePRG Yes, an exit status of 0 indicates success - it's not a boolean value. Commands can return any exit status from 0 to 255, which is used to inform the user / other programs what kind of error happened (where "0" is "no error"). – Zero Piraeus Jun 3 '13 at 4:35
2  
You must be careful with the quoting. test -n $foo is a disaster waiting to happen because it will succeed if foo is undefined, but not if foo is of zero length. test -z $foo works as expected (ie, it succeeds both when foo is undefined and when foo is of zero length), but it is a good idea to use test -z "$foo" and avoid the pathological case. (test -z $foo succeeds when foo is undefined because the string -z is non-empty.) – William Pursell Jun 3 '13 at 13:32
    
@WilliamPursell Good catch - I've added a little to the answer per your comment. – Zero Piraeus Jun 3 '13 at 13:47

test command looks for mentioned file in current folder, If you want check file from another location provide with full path and don't use -z option or use -s option . You can do as below:

test /usr/bin/logname && echo $LOGNAME || echo Logname is not defined

or

test -s /usr/bin/logname && echo $LOGNAME || echo Logname is not define

share|improve this answer
1  
Suggest you read the question again ... – Zero Piraeus Jun 3 '13 at 4:21
    
According to you if 'test -z $LOGNAME && echo Logname is not defined' is correct then it print the output of 'test -z $LOGNAME && echo $LOGNAME || echo Logname is not define' should correct output. Anyway thanks for your suggestion. – Bobbin Zachariah Jun 3 '13 at 4:39
    
Nope - you don't understand how test -z works. Try it for yourself. – Zero Piraeus Jun 3 '13 at 4:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .