0

I have the following piece of code where I am trying to match the word "test" in the given string:

str="some test string"

if [ $str == *"test"* ]; then # [: too many arguments
    echo "string was found"
else
    echo "string was not found"
fi

Output:

string was not found

Bash version:

GNU bash, version 4.4.23(1)-release (x86_64-pc-msys)

What am I doing wrong?

0stone0
  • 34,288
  • 4
  • 39
  • 64
meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
  • 1
    `if [[ "$str" == *"test"* ]]; then` (Note the quotes around `$str` and the double `[[ ]]`) – 0stone0 Oct 29 '21 at 09:58
  • @0stone0 there is where I tried from and I still get the same output and an error saying *[: too many arguments* – meJustAndrew Oct 29 '21 at 09:59
  • Are you sure you're using bash? PLease share the version. The above should work [as you can test in this online demo](https://tio.run/##bYtBCoAwEAPvfUVYPPUL0peIh6pbW9AW3BWfXyvizdySmUxeYq2ihyMpO0NZFK2mvJIxKWAYQF0bCM7B0sPJYhx7aORs0MJzLKD3hMsLQjnzQoY34X8hF/2kkGq9AQ) – 0stone0 Oct 29 '21 at 10:00
  • @0stone0 thanks for your help! I am using bash under windows, I've edited the question to reflect the version. – meJustAndrew Oct 29 '21 at 10:03
  • Ahh, not sure if WSL has any different behavior regarding this. Maybe you can include the fact that you're running this on WSL in the question? – 0stone0 Oct 29 '21 at 10:05
  • 1
    When using `[`, the LHS operand always needs to be quoted `"$str"` – Inian Oct 29 '21 at 10:06
  • @Inian I've tried with it quoted and it produces the same output and error. I believe as 0stone0 mentioned, it's something related to running it under windows – meJustAndrew Oct 29 '21 at 10:08
  • 3
    @meJustAndrew `[ ]` and `[[ ]]` have significantly different syntaxes, and only `[[ ]]` can do pattern matching like you're trying to do. You *must* switch to the double-bracket version for this. See [BashFAQ #13: "What is the difference between `test`, `[` and `[[` ?"](http://mywiki.wooledge.org/BashFAQ/031) and the Unix & Linux question ["What is the difference between the Bash operators `[[` vs `[` vs `(` vs `((`?"](https://unix.stackexchange.com/questions/306111/what-is-the-difference-between-the-bash-operators-vs-vs-vs) – Gordon Davisson Oct 29 '21 at 10:38

1 Answers1

1

this part [ $str == *"test"* ] is evaluated as a file-pattern glob. And if you have several files in that dir starting with test, you get "too many arguments"

Essentially, this is being evaluated [ $str == somethingttest testish test ], but [] with == wants only three arguments.

Another problem is using patterns with [ ]. It's not supported afaik. If you want to match against a pattern use [[ $foo =~ PATTERN ]], or [[ $str =~ test ]] in your case.

  • That was brilliant! I had indeed one file locally called test. Removing it made the error go away, but the string was still not found. And after adding two sets of square braces instead of one the string got matched. Thanks a lot! – meJustAndrew Oct 29 '21 at 10:39
  • 1
    btdt... np. just stick to double brackets unless you have reasons not to, they are much safer. – Ярослав Рахматуллин Oct 29 '21 at 10:42
  • 1
    `[[ .. ]]` supports both shell patterns (`*test*`) with `=` or `==`, or regular expressions with `=~`. In other words, `[[ $str == *test* ]]` would work as well. Notice that the left-hand side is quoted for us, so we don't have to take care of it (it wouldn't hurt, though), and the right-hand side *must not* be quoted or the pattern isn't recognized as such. – Benjamin W. Oct 29 '21 at 10:46