0

Question

Hi, as far as I know, in the bash, conditional statement can be shorten using the [ ] and && (for true condition) or || (for false condition) to specify which action should be done depending on the condition.

Also, the action list can consist of multiple commands which is separated by the semicolon (;).

For example, as shown in the below source code.

[ ! $# == 2 ] && ( echo "Usage: $0 weight_in_killos length_in_centimeters"; exit)

However, it seems that the exit command does not executed after the echo prints a string.

Please go over the below source code and let me know the problem.

Sourcecode

#!/bin/bash

[ ! $# == 2 ] && ( echo "Usage: $0 weight_in_killos length_in_centimeters"; exit)

if [ ! $# == 2 ]; then 
  echo "Usage: $0 weight_in_killos length_in_centimeters"
  exit   
fi

weight=$1
height=$2

idealweight=$(($height-110))
echo $idealweight

if [ "$weight" \< "$idealweight" ]; then
  echo "eat more"
elif [ "$weight" -eq "$idealweight" ]; then
  echo "fit well"
else
  echo "eat less" 
fi

Interestingly to me, it executes the two echo from the first conditional (shorten version) and the second conditional (if statement).

I've expected it will only print one echo message and exit because the first echo is followed by the exit command.

7
  • 2
    the ( ... ; exit ) section is run as a sub-shell (because of the parens). The exit applies to exiting the sub-shell. In your example case, you don't really need the parens, but you'll have to chain all cmds with &&, i.e. [ cond ] && echo "msg" && exit . If you run the revised code on your command-line, be prepared for your shell/terminal to exit. Good luck. Commented Sep 27, 2017 at 3:28
  • 2
    @shellter It's technically possible for the echo command to fail, in which case the exit would not be executed. I'd recommend just using a proper if statement -- it doesn't suffer from any of these weird edge cases. Commented Sep 27, 2017 at 4:15
  • 1
    BTW, you probably want to use if [ "$weight" -lt "$idealweight" ]; then instead of \<. < does textual (alphabetic) comparison rather than numeric. For example, [ 110 \< 55 ] evaluates to true, because "1" comes before "5" in character sorting order. Commented Sep 27, 2017 at 4:21
  • @GordonDavisson Thanks for a kind explanation. I have some questions about your answers. First, what do you mean by failure in echo? Did you mean the case that echo returns non-zero value as an exit value? Is it possible that the echo returns non-zero, which means failure of echo command? Second, as far as I know, for numerical comparison, double parentheses (( )) are recommended, for example "if (( 110 < 55 ))". I couldn't really understand when should I use [ -lt, -gt, eq, etc ] , [ >, <, ==], and (( )). Thanks again. Commented Sep 27, 2017 at 7:32
  • 1
    Oh, another confusing thing: in (( )), a single equal sign (=) is assignment, and a double equal sign (==) tests for equality. In [ ] and [[ ]], a single equal sign is the equality test (as strings, so [ 05 = 5 ] is false), and double-equal is either a synonym for single equal (in bash) or unrecognized (some other shells). Oh, and read BashFAQ #31 for a good comparison of [ ] and [[ ]] (which unfortunately doesn't cover (( )) as well as I'd like). Commented Sep 27, 2017 at 17:06

1 Answer 1

0

Here's another way to conditionally group commands:

test $# -ne 2 && {
    echo "Usage: $0 weight_in_killos length_in_centimeters"
    exit
}
Sign up to request clarification or add additional context in comments.

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.