Unix & Linux
bash shell-script
Updated Sun, 11 Sep 2022 17:23:21 GMT

How can I loop this command in a bash script until the repsonse contains the string "connection successful"


I'm getting nowhere with this.

I simply want to make a bash script that loops 10 times and breaks if the output contains the string "connection successful".

I tried something like ret=$? and then if [$ret -ne 0] but I kept getting the else statement happen, even if ret is 1.

So now I'm trying to use grep to search for the words "connection successful", but I don't know how to use the syntax for that.

So I want something like:

for i in {1..10}
do
  ret=bluetoothctl connect 26:EE:F1:58:92:AF | grep "connection successful"
  if [$ret -ne ""]; then
    break
  fi
done

but obviously with the right syntax for $ret=bluetoothctl connect 26:EE:F1:58:92:AF | grep "connection successful"

Any help would be greatly appreciated.




Solution

It is rarely necessary to store the output from grep when you just want to test whether some text matches a pattern. Instead, just invoke grep with its -q option and act on its exit status:

#!/bin/sh
tries=10
while [ "$tries" -gt 0 ]; do
    if bluetoothctl connect '26:EE:F1:58:92:AF' | grep -q 'connection successful'
    then
        break
    fi
    tries=$(( tries - 1 ))
done
if [ "$tries" -eq 0 ]; then
    echo 'failed to connect' >&2
    exit 1
fi

If bluetoothctl returns a sane exit status on failure and success, then you don't even need grep and can shorten the if-statement in the loop into the following:

if bluetoothctl connect '26:EE:F1:58:92:AF' >/dev/null
then
    break
fi

In fact, you might as well make bluetoothctl part of the loop condition (assuming you switch from a for loop to using a while loop like I'm showing here):

#!/bin/sh
tries=10
while [ "$tries" -gt 0 ] && ! bluetoothctl connect '26:EE:F1:58:92:AF'
do
    tries=$(( tries - 1 ))
done >/dev/null
if [ "$tries" -eq 0 ]; then
    echo 'failed to connect' >&2
    exit 1
fi

Consider using https://www.shellcheck.net to verify the syntax of your shell scripts. For the script in the question, it would point out that the test needs spaces within the [ ... ]:

  if [$ret -ne ""]; then
  ^-- SC1009 (info): The mentioned syntax error was in this if expression.
     ^-- SC1035 (error): You need a space after the [ and before the ].
     ^-- SC1073 (error): Couldn't parse this test expression. Fix to allow more checks.
                  ^-- SC1020 (error): You need a space before the ].
                  ^-- SC1072 (error): Missing space before ]. Fix any mentioned problems and try again.

Testing for a non-empty string is done with [ -n "$ret" ] or [ "$ret" != "" ]. Note that -ne is an arithmetic test.

You also do not assign the output of the pipeline correctly to ret. Unfortunately, the syntax is absolutely correct but does something completely different, so ShellCheck would not pick up on it. What you intended to use was

ret=$( bluetoothctl ... | grep ... )






External Links

External links referenced by this document: