0

I'm writing some very simple Bash scripts and I've become a tad bit stuck.

I would like the script I'm attempting to write to be able to differentiate between "non valid inputs ie letters" from "valid inputs ie numbers from a specific range"

Currently the script "works" although I'm having troubles with another echo that I would like only to "echo" when the below line is "not true", is there a simple way to write this? I'm not specifically looking for efficient code, just code that I can learn from and understand at my amateur level.

So, long story short, is it possible to obtain information from the command line below, so that I can have a simple "not true" variable that I can use in another "else" or "elif" command?

For reference line 1 is to detect alphabetical inputs, and line 2 being the line of code I would like to write as "not true" for use in another part of my script.

  1. let xx=$a+1-1 2>/dev/null; ret=$?

  2. if [ $a -ge 7 ] && [ $a -le 70 ] && [ $xx -eq $xx ] && [ $ret -eq 0 ]

4
  • Always QUOTE YOUR VARIABLES in [ .. ] (there is no need in [[ .. ]]), but in [ .. ] it is mandatory. ([ .. ] is an alias for test). To suppress the error when a non-integer is entered for xx, you can [ "$xx" -eq "$xx" 2>/dev/null ] to redirect stderr to /dev/null (the bit-bucket...) Commented May 18, 2021 at 2:27
  • 3
    It worth bookmarking the guides Bash Guide, Bash FAQ, and Bash Pitfalls (especially the Pitfalls :) along with shellcheck.net Spending a bit of time with the Advanced Bash-Scripting Guide is time well spent. Commented May 18, 2021 at 2:30
  • 1
    In addition to the treasure troves of information others have linked, click the bash tag under your question, then click "Learn more..." for the bash tag wiki here on stackoverflow. Commented May 18, 2021 at 2:45
  • @JB : I would detect input containing an alphabetic character by doing [[ $a == *[A-Za-z]* ]]. Checking whether a contains any nun-numeric character can be done by [[ $a == *[^0-9]* ]]. Commented May 18, 2021 at 5:11

2 Answers 2

2

If I read it right:

typeset -i xx # accepts only digits now.

If the input is foo, the value defaults to 0, so now just check the range.

if (( xx >= 7 && xx <= 70 )); then : value is ok
else echo "Value must be a number from 7 to 70"
     exit 1
fi

I also recommend the following useful resources: the Bash manual and the BashFAQs.

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

1 Comment

NOTE: this method will allow some odd entries to slip through - for example, assigning xx=0xdeadbeef will actually store 3735928559, since it's a valid hex-formatted value...
0

One problem with the "variable with integer attribute" is that it still doesn't protect you from invalid input:

$ declare -i aNumber
$ aNumber=1234X
bash: 1234X: value too great for base (error token is "1234X")

See 6.5 Shell Arithmetic for how bash interprets values to be numbers (scroll down to the paragraph starting with "Integer constants follow the C language definition")

In my experience, the best way to check for valid numeric input is with string-oriented pattern matching.

if [[ $1 =~ ^[+-]?[0-9]+$ ]]; then
    echo "input $1 is an integer"
fi

In addition to extended regular expressions, bash's advanced pattern matching can also be used within [[...]]

if [[ $1 == ?([+-])+([0-9]) ]]; then
    echo "input $1 is an integer"
fi

((...)) is preferred over let. See the let builtin command for details. Also the shellcheck wiki entry.

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.