0

I am passing command line arguments to a script, say a.sh.

From a.sh, I use "$@" to pass all those arguments to another bash script (user_pref.sh). In this bash file, I am trying to assign either 0 or 1 based on the parameters received from a.sh using basic if condition. But for some reason, I am not able to reason the correct value and all my variables are set to 0. I am new to bash scripting and would really appreciate any help here. I have referred different post on the site but they have not helped me resolve my issue so far.

a.sh code

#!/bin/bash

/home/postgres/viraltest_scripts/user_pref.sh "$@" &> /home/postgres/viraltest_scripts/logs/refresh_dev_sql.log

user_pref.sh Code:

#!/bin/bash
## assigning default values
a=1
b=1
c=1
if [[ $1 -eq 0 ]]
then
    a=0
fi

if [[ $2 -eq 0 ]]
then
    b=0
fi

if [[ $3 -eq 0 ]]
then
    c=0
fi

Irrespective of what I pass from a.sh, All the variables in user_pref.sh are assigned 0. Can anyone point out what am I doing wrong with the If statement? PS: I am aware of assigning a=$1 but for the purpose of my application, I have to explicitly assign 0 or 1 instead of doing a=$1.

7
  • Are you passing arguments that are integers? [[ non_integer_value -eq 0 ]] is true and does not emit any error message. Commented Oct 27, 2017 at 15:27
  • Welcome to the site! Check out the tour and the how-to-ask page for more about asking questions that will attract quality answers. Would you please edit your question to include the relevant portions of a.sh? It is difficult to know exactly what you are trying to accomplish otherwise. Thanks! Commented Oct 27, 2017 at 15:28
  • I am passing only integers, 0 and 1 specifically. Commented Oct 27, 2017 at 15:28
  • @cxw I have edited the question with the a.sh file. Thank you for such prompt reply :) Commented Oct 27, 2017 at 15:32
  • 1
    What shell is this? /bin/sh may not be what you think it is. If you want bash, say so. Try running with bash -x a.sh to see what's happening. Commented Oct 27, 2017 at 15:46

3 Answers 3

3

Edit The first line of your file should be #!/bin/bash, not #!/bin/sh. You are using bash extensions, so make sure you are asking that the script be interpreted by bash (and not sh, dash, csh, ...).

Second, -eq tests for numeric equality, not string equality. As a result, [[ '' -eq 0 ]] is true. I think you may want [[ $# -ge 1 && $1 = 0 ]], and similar tests throughout. $# -ge 1 checks if a parameter was actually provided, and then = tests for string equality. Like this:

a=1
if [[ $# -ge 1 && $1 = 0 ]]; then a=0 ; fi
b=1
if [[ $# -ge 2 && $2 = 0 ]]; then b=0 ; fi
c=1
if [[ $# -ge 3 && $3 = 0 ]]; then c=0 ; fi

Edit 2 Not sure if this meets your requirements, but since you are only passing 0 or 1, you can use default assignments:

a="${1:-1}"
b="${2:-1}"
c="${3:-1}"

"${foo:-def}" is a substitution with a default value. If $foo is unset or null, def is the result; otherwise, $foo is the result.

Test

Per the OP's comment:

$ cat a.sh
#!/bin/bash
./user_pref.sh "$@"

$ cat user_pref.sh
#!/bin/bash
set -x
a=1
if [[ $# -ge 1 && $1 = 0 ]]; then a=0 ; fi
b=1
if [[ $# -ge 2 && $2 = 0 ]]; then b=0 ; fi
c=1
if [[ $# -ge 3 && $3 = 0 ]]; then c=0 ; fi
echo a-"$a"- b-"$b"- c-"$c"

$ ./a.sh
+ a=1
+ [[ 0 -ge 1 ]]
+ b=1
+ [[ 0 -ge 2 ]]
+ c=1
+ [[ 0 -ge 3 ]]
+ echo a-1- b-1- c-1
a-1- b-1- c-1

A case giving it a 1 manually (even though 1 is the default):

$ ./a.sh 1
+ a=1
+ [[ 1 -ge 1 ]]       <--- it saw the parameter
+ [[ 1 = 0 ]]
+ b=1
+ [[ 1 -ge 2 ]]
+ c=1
+ [[ 1 -ge 3 ]]
+ echo a-1- b-1- c-1
a-1- b-1- c-1

The case I think the OP is referring to:

$ ./a.sh 0
+ a=1
+ [[ 1 -ge 1 ]]       <--- it saw the parameter...
+ [[ 0 = 0 ]]
+ a=0                 <--- ...and it overrode the default.
+ b=1
+ [[ 1 -ge 2 ]]
+ c=1
+ [[ 1 -ge 3 ]]
+ echo a-0- b-1- c-1
a-0- b-1- c-1

$ ./a.sh 0 0 0
+ a=1
+ [[ 3 -ge 1 ]]
+ [[ 0 = 0 ]]
+ a=0
+ b=1
+ [[ 3 -ge 2 ]]
+ [[ 0 = 0 ]]
+ b=0
+ c=1
+ [[ 3 -ge 3 ]]
+ [[ 0 = 0 ]]
+ c=0
+ echo a-0- b-0- c-0
a-0- b-0- c-0
Sign up to request clarification or add additional context in comments.

5 Comments

the if condition always returns false even when a parameter is 0. I checked by running set -x, it reads [[ $# -ge 1 && $1 = 0 ]] to [[ 0 -ge 1 ]] and then skips the rest of the if statement
@vsh9 When running ./a.sh? If you don't pass any parameters, you'll get the default values (1). See edit.
Your suggestion works. Thanks a lot for your help. I have marked your comment as my answer!
I did, it should be visible
@vsh9 yep, it is now. Thanks!
1
a=$(( $# > 0 ))
b=$(( $# > 1 ))
c=$(( $# > 2 ))

$# is the number of positional parameters received. If $# > 0, you know you got at least one argument, so a should be 1, or 0 otherwise. In an arithmetic expression, a true boolean value evaluates to 1, a false to 0. Likewise, if $# is at least 2, then b should be 1, etc.

If you are certain that the passed parameters will be 0 or 1, and you simply want to default to 0 if a parameter is missing, use

a=${1:-0}
b=${2:-0}
c=${3:-0}

in which each parameter expansion evaluates to 0 if the given parameter is null or unset.

Comments

0

Seems easier to do:

test -z "$1"
a=$?
test -z "$2"
b=$?
test -z "$3"
c=$?

(This implements the logic that I think you are trying to get at. Namely, assign the value 1 if the respective parameter is non-empty, 0 otherwise.)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.