LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Limit in bash for conditions? (https://www.linuxquestions.org/questions/linux-newbie-8/limit-in-bash-for-conditions-671065/)

webaccounts 09-19-2008 09:16 AM

Limit in bash for conditions?
 
I'm getting this error when I run a script.
Code:

[root@lnxapp bin]# ./update-chapter-webpage
./update-chapter-webpage: line 270: [: too many arguments
./update-chapter-webpage: line 270: [: too many arguments
./update-chapter-webpage: line 270: [: too many arguments
./update-chapter-webpage: line 270: [: too many arguments
./update-chapter-webpage: line 270: [: too many arguments

This is the code. "if" is line 270 that the error refers too.
Code:

state=`cat $webroot/$basename/state`
        if [ $state != "Alabama" ] && [ $state != "Alaska" ] && [ $state != "Arizona" ] && [ $state != "Arkansas" ] && [ $state != "California" ] && [ $state != "Colorado" ] && [ $state != "Connecticut" ] && [ $state != "Delaware" ] && [ $state != "Florida" ] && [ $state != "Georgia" ] && [ $state != "Hawaii" ] && [ $state != "Idaho" ] && [ $state != "Illinois" ] && [ $state != "Indiana" ] && [ $state != "Iowa" ] && [ $state != "Kansas" ] && [ $state != "Kentucky" ] && [ $state != "Louisiana" ] && [ $state != "Maine" ] && [ $state != "Maryland" ] && [ $state != "Massachusetts" ] && [ $state != "Michigan" ] && [ $state != "Minnesota" ] && [ $state != "Mississippi" ] && [ $state != "Missouri" ] && [ $state != "Montana" ] && [ $state != "Nebraska" ] && [ $state != "Nevada" ] && [ $state != "New Hampshire" ] && [ $state != "New Jersey" ] && [ $state != "New Mexico" ] && [ $state != "New York" ] && [ $state != "North Carolina" ] && [ $state != "North Dakota" ] && [ $state != "Ohio" ] && [ $state != "Oklahoma" ] && [ $state != "Oregon" ] && [ $state != "Pennsylvania" ] && [ $state != "Rhode Island" ] && [ $state != "South Carolina" ] && [ $state != "South Dakota" ] && [ $state != "Tennessee" ] && [ $state != "Texas" ] && [ $state != "Utah" ] && [ $state != "Vermont" ] && [ $state != "Virginia" ] && [ $state != "Washington" ] && [ $state != "Washington DC" ] && [ $state != "West Virginia" ] && [ $state != "Wisconsin" ] && [ $state != "Wyoming" ] && [ $state != "Canada" ] && [ $state != "Europe" ] && [ $state != "Other" ]
        then
                echo "Unknown" > $webroot/$basename/state
        fi

My question is, I don't see whats wrong with that area other than maybe it doesn't like that many conditions. Is there something I'm missing?

CRC123 09-19-2008 09:31 AM

I was able to recreate the same error when $state held more than one word. So it fails when
Code:

echo $state
returns something like this:
Code:

word1 word2..etc
Make sure there is only one word inside $state and that there are no spaces.

makyo 09-19-2008 09:47 AM

Hi.

There are a few ways of dealing with this:
Code:

#!/bin/bash -

# @(#) s1      Demonstrate command test as bracket, quoting.

echo
echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version "=o" $(_eat $0 $1)
set -o nounset

echo
echo " Results with single [, no quotes:"
for state in Minnesota "New Jersey"
do
  if [ $state != Minnesota ]
  then
    echo " state is not Minnesota: :$state:"
  else
    echo " state is Minnesota"
  fi
done

echo
echo " Results with single [, quotes:"
for state in Minnesota "New Jersey"
do
  if [ "$state" != Minnesota ]
  then
    echo " state is not Minnesota: :$state:"
  else
    echo " state is Minnesota"
  fi
done

echo
echo " Results with double [, no quotes:"
for state in Minnesota "New Jersey"
do
  if [[ $state != Minnesota ]]
  then
    echo " state is not Minnesota: :$state:"
  else
    echo " state is Minnesota"
  fi
done

exit 0

Producing:
Code:

% ./s1

(Versions displayed with local utility "version")
Linux 2.6.11-x1
GNU bash 2.05b.0

 Results with single [, no quotes:
 state is Minnesota
./s1: line 14: [: too many arguments
 state is Minnesota

 Results with single [, quotes:
 state is Minnesota
 state is not Minnesota: :New Jersey:

 Results with double [, no quotes:
 state is Minnesota
 state is not Minnesota: :New Jersey:

Best wishes ... cheers, makyo

i92guboj 09-19-2008 10:47 AM

Quote correctly your variables unless you are SURE that they will never hold special characters like spaces.

webaccounts 09-19-2008 10:51 AM

Thanks for the help. I didn't realize the 2 word ones.

I fixed it by changing it from
Code:

if [ $state != "Alabama" ] .....
to
Code:

if [ "$state" != "Alabama" ] .....

David1357 09-19-2008 11:12 AM

Quote:

Originally Posted by webaccounts (Post 3285743)
I fixed it by changing it from
Code:

if [ $state != "Alabama" ] .....
to
Code:

if [ "$state" != "Alabama" ] .....

You probably want to use
Code:

if [ "x$state" != "xAlabama" ] .....
This handles the problem that $state has not been initialized.

Valery Reznic 09-21-2008 03:01 AM

Quote:

Originally Posted by David1357 (Post 3285757)
You probably want to use
Code:

if [ "x$state" != "xAlabama" ] .....
This handles the problem that $state has not been initialized.

I found that following code is more readable:
case "x$state" in
xAlabama | \
xAlaska | \
xArizona | \
xLastValue)
DoSomething
;;

*)
DoSomethingElse
;;
esac

makyo 09-21-2008 08:25 AM

Hi.

The uninitialized variable situation could be addressed generally with bash setting nounset. The double brackets also handle uninitialized variables -- for example:
Code:

#!/bin/bash -

# @(#) s2      Demonstrate comparison of single and double brackets.

echo
echo "(Versions displayed with local utility \"version\")"
version >/dev/null 2>&1 && version "=o" $(_eat $0 $1)

echo
echo " Results, single:"
if [ $state != Minnesota ]
then
  echo " State is not Minnesota ( single [] ), :$state:"
fi

echo
echo " Results, double:"
if [[ $state != Minnesota ]]
then
  echo " State is not Minnesota ( double [[]] ), :$state:"
fi

exit 0

Producing:
Code:

% ./s2

(Versions displayed with local utility "version")
Linux 2.6.11-x1
GNU bash 2.05b.0

 Results, single:
./s2: line 11: [: !=: unary operator expected

 Results, double:
 State is not Minnesota ( double [[]] ), ::

I like the case suggestion.

We don't know how often this code is executed, but if it is a "large number" of times, then there is a clever post at http://groups.google.com/group/comp....be3dcd9?hl=en# that may be useful. It shows how a hash function can be written for bash. The displayed code used a complicated method for the hash, which I replaced that with cksum because I found that easier to read. The array needs to be initialized, but after that, the hash of the text to lookup only needs to be calculated (and presumably checked for existence). If I had to guess, it's probably more useful for a large number of items through which to search, as opposed to a large number of executions, and also where a dynamic capability is required. Even if not useful in this situation, it might be for some other problem. It would be interesting to compare the methods -- an exercise for the reader.

Best wishes ... cheers, makyo


All times are GMT -5. The time now is 04:45 PM.