7

What's the best way to convert a literal string (e.g. "True" into the appropriate bash boolean variable). For instance java has java.lang.Boolean.valueOf(String)

Right now I'm using this in Bash:

if [ "${answers[2]}" = "TRUE" ] ; then
    clean=true; 
else 
    clean=false; 
fi

is there a way to do it and avoid the IF statement?

edit: to clarify its not by choice that I have String variable containing "TRUE" instead of just using a boolean variable. for full context this is the code

ans=$(yad --title='YadExample' --form --field=Opt1:CHK FALSE  --field=Opt2:CHK FALSE --field=Opt3:CHK TRUE);
#at this point the "yad" program is returning a string seperated by '|', e.g "TRUE|FALSE|TRUE"
IFS="|"
set -- $ans
answers=( $@ )
unset IFS
if [ "${answers[0]}" = "TRUE" ] ; then clean=true; else clean=false; fi
if [ "${answers[1]}" = "TRUE" ] ; then var2=true; else var2=false; fi
if [ "${answers[2]}" = "TRUE" ] ; then var3=true; else var3=false; fi
2
  • Where is the answers array coming from? What are possible entry values? Commented Feb 5, 2013 at 5:18
  • I added more context to the question to explain how I get to the If statement Commented Feb 5, 2013 at 5:22

2 Answers 2

5

You could write a function to do the conversion for you:

function boolean() {
  case $1 in
    TRUE) echo true ;;
    FALSE) echo false ;;
    *) echo "Err: Unknown boolean value \"$1\"" 1>&2; exit 1 ;;
   esac
}

answers=(TRUE FALSE TRUE)
clean="$(boolean "${answers[0]}")"
var2="$(boolean "${answers[1]}")"
var3="$(boolean "${answers[2]}")"

echo $clean $var2 $var3

prints

true false true

Or, a little fancier:

function setBoolean() {
  local v
  if (( $# != 2 )); then
     echo "Err: setBoolean usage" 1>&2; exit 1 ;
  fi

  case "$2" in
    TRUE) v=true ;;
    FALSE) v=false ;;
    *) echo "Err: Unknown boolean value \"$2\"" 1>&2; exit 1 ;;
   esac

   eval $1=$v
}

answers=(TRUE FALSE TRUE)

setBoolean clean "${answers[0]}"
setBoolean var2 "${answers[1]}"
setBoolean var3 "${answers[2]}"

echo $clean $var2 $var3
Sign up to request clarification or add additional context in comments.

4 Comments

ah nice. This is pretty much what I was looking for. I wanted to avoid cluttering the code with if statements for something that I might need to do a lot. This function is a good abstraction. Didn't know you could set variables like that from functions, thanks!
I would use declare instead of eval in this case. It's safer (you can't execute arbitrary code from $1), and you're already using bash-specific features.
@chepner When I change eval $1=$v to declare $1=$v, the script stops working :/ I think it’s because it’s being used inside a function, but I’m not completely sure.
Of course. I didn't pay attention to the scope. I guess this is a case where there isn't a good alternative to eval for earlier versions of bash. Version 4.2 of bash does include a -g option for declare so that it can create global functions inside a function.
3

You can just use something like:

[ "${answers[2]}" != "TRUE" ] ; clean=$?

You need to reverse the sense of the comparison if you want clean set to 1 on the condition being true.

Your sequence then becomes:

[ "${answers[0]}" != "TRUE" ] ; clean=$?
[ "${answers[1]}" != "TRUE" ] ; var2=$?
[ "${answers[2]}" != "TRUE" ] ; var3=$?

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.