345

I am doing some bash script and now I got one variable call source and one array called samples, like this:

source='country'
samples=(US Canada Mexico...)

as I want to expand the number of sources (and each source has its own samples) I tried to add some arguments to do this. I tried this:

source=""
samples=("")
if [ $1="country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
   echo "try again"
fi

but when I ran my script source countries.sh country it didn't work. What am I doing wrong?

4
  • 2
    how does it not work? When you run it you get an error, or it says "try again", or something else? Commented Mar 15, 2012 at 20:42
  • 2
    yes, you may think 'the question is very straightforward'. but you've been thinking about this for a while. Please consider editing your question to include required outputs and any error messages you're getting. +1 for actually trying something and good formatting of question. good luck. Commented Mar 15, 2012 at 20:46
  • 1
    Why is this code the same as the proposed and accepted solution? That's confusing... I'm guessing the initial question didn't have the spaces right after the opening bracket and before the closing bracket of the if sentence? Commented Apr 5, 2016 at 5:32
  • 7
    @Stef if you look closely, $1="country" vs. $1 = "country" Commented Oct 18, 2017 at 20:46

3 Answers 3

593

Don't forget about spaces:

source=""
samples=("")
if [ $1 = "country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
  echo "try again"
fi
Sign up to request clarification or add additional context in comments.

10 Comments

I cannot believe that I expend three hours on this, and was only a problem of spaces!!!!... THANKS @Alex
I ran into issues with this when the variable on the left was an empty string. Fix was if [ "$1" = "country" ]; then.
Okay thats it. Bash officially gets my vote for beeing the most outdated yet still used command language. Syntax is just so non intuitive it hurts. Really no place for it in 2016+. @Systemd authors: can you please make "building a Linux shell that doesn't suck" your next project? I'll throw money at you.
@masi sometimes i think the original intent of unix was "job security through obscurity". if the tools were cryptic to use, hard to understand, and generally out of reach of the great unwashed without the inside knowledge handed down from master to padwan, it would ensure that there would always be work for those "in the know". this philosophy is evident in the whole "RFC" construct, and flowery language used in man documents, which whilst technically telling you how to use the tools, really just were there to fulfill a requirement of having documented the tools. little has changed.
If scripts are at all 'logic-heavy' (>1 if, >0 while...) I strongly try to use Python. subprocess.run and os.exec* can go pretty far.
|
280

You can use either "=" or "==" operators for string comparison in bash. The important factor is the spacing within the brackets. The proper method is for brackets to contain spacing within, and operators to contain spacing around. In some instances different combinations work; however, the following is intended to be a universal example.

if [ "$1" == "something" ]; then     ## GOOD

if [ "$1" = "something" ]; then      ## GOOD

if [ "$1"="something" ]; then        ## BAD (operator spacing)

if ["$1" == "something"]; then       ## BAD (bracket spacing)

Also, note double brackets are handled slightly differently compared to single brackets ...

if [[ $a == z* ]]; then   # True if $a starts with a "z" (pattern matching).
if [[ $a == "z*" ]]; then # True if $a is equal to z* (literal matching).

if [ $a == z* ]; then     # File globbing and word splitting take place.
if [ "$a" == "z*" ]; then # True if $a is equal to z* (literal matching).

Comments

17

It seems that you are looking to parse commandline arguments into your bash script. I have searched for this recently myself. I came across the following which I think will assist you in parsing the arguments:

http://rsalveti.wordpress.com/2007/04/03/bash-parsing-arguments-with-getopts/

I added the snippet below as a tl;dr

#using : after a switch variable means it requires some input (ie, t: requires something after t to validate while h requires nothing.
while getopts “ht:r:p:v” OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         t)
             TEST=$OPTARG
             ;;
         r)
             SERVER=$OPTARG
             ;;
         p)
             PASSWD=$OPTARG
             ;;
         v)
             VERBOSE=1
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z $TEST ]] || [[ -z $SERVER ]] || [[ -z $PASSWD ]]
then
     usage
     exit 1
fi

./script.sh -t test -r server -p password -v

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.