FINALLY! SOME UPDATES! This website is being reconstructed. Some content will go away soon. If you want to see my new stuff, visit my github: https://github.com/jrcharney/.

September 18, 2012

Bash Conditional Operator

Working on the new.sh and new_c.sh projects today, and I though it was about time to resolve a vexing issue: can bash execute conditional operations like in several other programming languages like C, C++, Java, PHP, etc.?

The answer is a resounding "YES!"

Firstly, what is the conditional operator? The conditional operator is the ternary operator that many programming languages have to execute an "if-then-else" (or "if-else" if you prefer to say it like that), in a single line. The following figure demonstrates its usefulness.

Without ?: With ?:
if ( a == b ) {
 return x;
} else {
 return y;
}
return ( a == b ) ? x : y;
The code on the right eliminated four lines of code.

Sure, you can argue that you could write the code on the left as

if (a == b ) { return x; } else { return y; }

But look how much better the code on the right looks. Add to that, only one return is used.

Commonly, the conditional operator is use for conditional assignment, as demonstrated in the next figure which looks quite similar to the previous figure.

Without ?: With ?:
if ( a == b ) {
 c = x;
} else {
 c = y;
}
c = ( a == b ) ? x : y;
Conditional assignment, FTW!

In some languages, assuming they got their order of operations right, you could even get away with this line of code.

c += ( a == b ) ? x : y;  // c = c + (x or y)

I know this isn't a big deal if C, C++, Java, JavaScript, or PHP are you forte, but but what about Bash? Bash is so literal at times.

Let's take the following code example. This next figure demonstrates a Bash, if-then-else statement, assuming we don't add any short cuts to the syntax.

if [[ $a -eq $b ]]
then
 c=$x
else
 c=$y
fi
See how much space this wastes?

Most of the time you can add a semicolon between the right test bracket. You can also do this with for, while and until loops with the do keyword.

if [[ $a -eq $b ]]; then
 c=$x
else
 c=$y
fi
Subtile.

So we made no significant change to this line of code. But we're only doing one thing. Let's flatten this to one line, like if we were trying something out in the command line.

if [[ $a -eq $b ]]; then c=$x; else c=$y; fi
Take note of where the semicolons are!

So we've managed to whittle this down to one line, but those keywords are still there. Here's where the magic happens.

[[ $a -eq $b ]] && c=$x || c=$y
I will now make the keywords disappear! TA DA!

"But this doesn't look like the condition operation syntax", I hear you cry. Well, let's make it look like it.

c=$( [[ $a -eq $b ]] && echo "$x" || echo "$y" )
The final form, at least for this example.

Now, I see there many be a few folks dissatisfied that a couple of echo commands got in there. There is of course this alternative.

function getX(){
 echo "$x"
}

function getY(){
 echo "$y"
}

c=$( [[ $a -eq $b ]] && getX || getY )
It looks like a conditional assignment to me!

or even

function getX(){
 c=$x
}

function getY(){
 c=$y
}

[[ $a -eq $b ]] && getX || getY
I'm pretty sure this works.

But honestly, I'm content with either of the following two forms.

 [[ $a -eq $b ]] && c=$x || c=$y 
 c=$( [[ $a -eq $b ]] && echo "$x" || echo "$y" )
They both work, and that is good enough for me!

At any rate, I'm considering practicing this syntax in the future, maybe even in the latest version of the new and new_c programs.

Tags

Under Construction