1

I have an if/else statement in a bash script that's asking if an EBS volume is going to be created from a snapshot id.

I'd like to create a line like: if [ "$from_snapshot" -eq "Y|y" ] but I don't think that will work.

Here's what I have:

  if [ "$from_snapshot" -eq "Y" ]
    then
      echo "Enter Snapshot ID: "
      read -r snapshot_id
   elif "$from_snapshot" -eq "y"
      echo "Enter Snapshot ID: "
      read -r snapshot_id
   else 
      echo "No Snapshot Required"
   fi

If there any way I can state that more succinctly?

2
  • 2
    Consider case $from_snapshot in [Yy]) echo "yes code goes here";; *) echo "other code goes here";; esac for a baseline-POSIX approach. Commented May 21, 2018 at 19:31
  • Alternatively, you could to change the case of your parameter: [[ ${from_snapshot^} = Y ]] or [[ ${from_snapshot,} = y ]] Commented May 21, 2018 at 22:04

2 Answers 2

5

The -eq operator in test (aka [) is used for arithmetic comparisons. That's certainly not what you want; you're trying to do a string comparison, which is the = operator. (Bash lets you type that as ==, but = is what the standard requires.)

With bash, you are much better off using the [[ conditional command, which allows for "glob"-style pattern comparisons (and also regular expressions if you need that). So you could use

if [[ "$from_snapshot" = [Yy] ]]; then 

Note: Do not put quotes around [Yy]. Quoting it will make it into a literal string instead of a pattern.

Sign up to request clarification or add additional context in comments.

Comments

2

In the more general case, you can use the -o option which performs a logical OR:

if [ \( "$from_snapshot" = "Y" \) -o \( "$from_snapshot" = "y" \) ]
then
  echo "Enter Snapshot ID: "
  read -r snapshot_id
else 
  echo "No Snapshot Required"
fi

Or you can use multiple tests with || between them:

if [ "$from_snapshot" = "Y" ] || [ "$from_snapshot" = "y" ]
then
  echo "Enter Snapshot ID: "
  read -r snapshot_id
else 
  echo "No Snapshot Required"
fi

1 Comment

Note the OB flags in the POSIX test spec -- passing more than four arguments to a single test command, or using -o, -a or parens, is obsolescent behavior (and an XSI extension, rather than baseline POSIX, even prior to that designation). The core issue is that it's ambiguous -- test can't tell if parens are intended to be literal or syntactic; is [ '(' = ')' ] supposed to be asking whether = is an empty string, with that test inside a group, or checking whether ( and ) are the same character?

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.