Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am using Redhat Enterprise 5.3, and I have a small script that reads the directory name and compares it against a variable. Something seems to be causing it to think I am trying to get it to run the directory name as a command, and it also does not correctly evaluate the directory name against the string...(the directory name is "ll_bkup"):

SCRIPT:

#!/bin/bash
# Changes backup folder to standard name after LogLogic System Stores a session number in t$
#TCJ 6/1/09

declare RESULT
cd /home/storegrid/scripts/test/backup
RESULT=$('ls')
TEST="ll_bkup"

if ["${RESULT}" = "${TEST}"]; then
        echo "it's ll_bkup"
else
        echo $RESULT
fi

exit 0

RESULT:

[root@NB-BACKUP-01 backup]# sh /home/storegrid/scripts/test/nb-script-changellbackup.sh
/home/storegrid/scripts/test/nb-script-changellbackup.sh: line 10: [ll_bkup: command not found
ll_bkup
share|improve this question
add comment

5 Answers 5

up vote 1 down vote accepted

String comparisons with shell are tricky. Everyone wants to use "if" and "test" but there is another structure that works really well for string matching.

The if structure really just checks the exit status of the last thing that runs after the if. The "[" is really the program "test" which can do string comparisons but can also do other things like check to see if a directory entry is a link or a directory or a file.

Also -- the variable=$(ls) structure is potentially going to do bad things if you have more than one directory entry in that directory, or if you have a name with whitespace in it. You're safer letting the shell do the globbing for you with something like a for loop.

Put it all together with:

#!/bin/sh
default_name=ll_bkup

if
  cd /home/storegrid/scripts/test/backup
then
  for result in *
  do
    case "$result"
    in
      "$default_name")
          if 
            test -d "$result"
          then
            echo "the default directory exists"
          else
            echo "the default directory exists but is not a directory!!"
            exit 33
          fi
         ;;
       *)
         if
           test -d "$result"
         then
           echo "non-standard directory $result exists"
         else
           echo "file named $result exists in directory $(pwd)"
         fi
        ;;
    esac
  done
else
  echo "directory doesn't exist or permission problem!"
  exit 40
fi
share|improve this answer
add comment

${foo} is a syntax for dereferencing array elements in bash. Other answers point out its general use in variable evaluation, but you don't need it here. You probably want to just compare

[ $RESULT = $TEST ]

Are you looking for a directory called ll_bkup? You could do

[ -d ll_bkup ]

for "ll_bkup exists and is a directory". Use -f if it is a file.

If you are looking for the contents being only ll_bkup, you can also do a test on

[ $(ls | wc -l) == 1 ]

Look at 'man test' for the syntax you can use.

There may be a more succinct way to do this, but learning the parts one at a time gives you a good understanding of the parts, and you can work your way up to more interesting tests with utilities like find.

share|improve this answer
    
Thanks, this is what I needed: [ -d ll_bkup ] –  TrevJen Jun 18 '09 at 17:03
add comment

In the second example you need a space after the '[' and before the ']' chars.

I.e.:

if [$RESULT = $TEST]; then

Should be:

if [ $RESULT = $TEST ]; then

This is because [ is actually a command not just some syntax in bash (although I believe there is a bash builtin [ too!!).

E.g. if you run the following in your shell:

# ls -l /usr/bin/[

it should show an executable file, e.g.:

-rwxr-xr-x 1 root root 43648 2008-10-13 19:20 /usr/bin/[

So your script is not trying to run ll_bkup, rather it is trying to run a command called [ll_bkup - which does not of course exist.

What you really want to run [ with the arguments " $RESULT = $TEST ]"

(without the quotes but with the space before $RESULT)

Does that make sense?

share|improve this answer
    
Yes, thanks for the wxplanation. –  TrevJen Jun 20 '09 at 16:19
add comment
Still get the same results with that syntax:

if [$RESULT = $TEST]; then
        echo "it's ll_bkup"
else
        echo $RESULT
fi

exit 0

RESULT:

[root@NB-BACKUP-01 backup]# sh /home/storegrid/scripts/test/nb-script-changellbackup.sh
/home/storegrid/scripts/test/nb-script-changellbackup.sh: line 10: [ll_bkup: command not found
ll_bkup
share|improve this answer
    
echo $RESULT; echo $TEST Can you output what those variables are? –  crb Jun 18 '09 at 16:59
add comment

The spaces are what you need as Jason says.

if [ $RESULT = $TEST ]; then
    ^ space here    ^ and here

The {} should make no difference in your case. ${foo} is not just a syntax for dereferencing array elements in bash.

It is the better way to access variables. Check this.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.