1

if I run this, it doesnt print yes.

if [s == [Ss]]
then echo "yes"
fi

However, if I write double [], so will be like

if [[s == [Ss]]]
then echo "yes"
fi

it prints yes

I wonder WHY

3
  • 1
    You cannot use character classes (e.g. [...]) within test (synonymous with [...]). Only bash [[ ... ]] allows character classes within it. Commented Mar 15, 2019 at 5:55
  • It all depends on the result of the command [s. Try executing [s directly (it's an odd name for a command, but perhaps you have an executable with that name), but I would expect your first example to give an error similar to [s: no such command Commented Mar 15, 2019 at 14:54
  • Space error aside, [ and [[ are two different commands, and only [[ supports pattern matching with the =(=) operator. Commented Mar 15, 2019 at 21:35

3 Answers 3

1

Continuing from my comment, POSIX-shell does not allow the use of character classes (e.g. [...]) within test (synonymous with [...]). Only bash [[ ... ]] allows character classes within it.

If you have coreutils installed (about every distro does) you can still match a character list against the string returning the index (1-based) within the string of the first character in the character list. For your case you could use:

if [ $(expr index "s" "sS") -gt '0' ]; then
    echo yes; 
fi

Where expr index "s" "sS" is the usual form of index string charlist, which requires the use of expr before it.

If you are limited to POSIX shell, then you can sill use expr string : regex to match against a regular expression.

if [ $(expr "s" : '[sS]$') -gt '0' ]; then
    echo yes; 
fi

(note: the regex must match the entire contents of the string being tested against)

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

2 Comments

POSIX expr doesn't have an index subcommand. Use expr s : '[sS]$' instead.
@chepner You are right match (or ':') is the only POSIX expr. Ahah! is coreutils that proves : match substr index length. Updated.
0

When comparing strings, the double-bracket syntax features shell globbing. As you are trying to compare with both the upper case and lower case. Also the double bracket syntax helps in Regex pattern matching. The condition you gave is similar to

if [[ "$stringvar" == *string* ]]; then

This means that an asterisk (“*”) will expand to literally anything, just as you probably know from normal command-line usage. Therefore, if $stringvar contains the phrase “string” anywhere, the condition will return true. Other forms of shell globbing are allowed, too. If you’d like to match both “String” and “string”, you could use the following syntax:

if [[ "$stringvar" == *[sS]tring* ]]; then

Comments

0

[ doesn't support pattern-matching. Use case instead.

inp=s

case $inp in
  [sS]) echo "Matched s/S" ;;
  *) echo "Did not match s/S" ;;
esac

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.