0

I am trying to figure out how to get my bash script to work. I have a the following command:

curl http://192.168.1.2/api/queue | grep -q test

I need it to repeat until the first command in the pipline succeeds (meaning the server responds) and the second command fails (meaning the pattern is not found or the queue is empty). I've tried a number of combinations but just can't seem to get it. I looked at using $PIPESTATUS but can't get it to function in a loop how I want. I've tried all kind of variations but can't get it to work. This is what I am currently trying:

while [[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 1 ]]
  do curl http://192.168.1.2 | grep -q regular
  echo "The exit status of first command ${PIPESTATUS[0]}, and the second command ${PIPESTATUS[1]}"
  sleep 5 
done
user2328273
  • 868
  • 3
  • 12
  • 22
  • Try `while [[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -gt 0 ]]`. Failing exit codes can be any non-zero integer. – Gavin Oct 04 '16 at 19:13
  • Still not working. It just exits with no output. – user2328273 Oct 04 '16 at 19:19
  • Have you tried echoing those two values before entering your loop? – Gavin Oct 04 '16 at 19:26
  • Well, I think that's part of my problem. It is a builtin variables that is assigned when a command is executed so they should be unvalued at that time, I think. I think there is something wrong with my assumptions. I'm just not experienced enough to know where to look. – user2328273 Oct 04 '16 at 19:29
  • If they won't have a value between when you call the commands and when you check them in the `while` conditional then why would they suddenly have a value in the conditional? You better echo the values before the while loop to see what's going on. – Gavin Oct 04 '16 at 19:31
  • `I'm just not experienced enough to know where to look` If you're having issues with entering a loop it's best to check out what your values are. This lets you see why you are or aren't entering. – Gavin Oct 04 '16 at 19:41
  • I'm not sure I'm making my point clear. Echoing PIPESTATUS before the loop isn't useful because I already know it is unvalued because it won't have a value until my `curl|grep` command. My understanding is that since the conditions to break out of the loop are `$PIPESTATUS[0]=0 and $PIPESTATUS[1]=1, and PIPESTATUS[*] has no value going into the loop, it should enter into the loop then once the `curl|grep` command executes $PIPESTATUS[*] will have values. Then it should repeat that loop until those values are 0 and 1. – user2328273 Oct 04 '16 at 20:34
  • I want to loop that piped curl/grep command until the curl command succeeds and the grep command fails. Maybe there is a better way to do that than evaluating PIPESTATUS in a loop but I don't know. Maybe I need an until loop but I couldn't get that to work either. If I use `while` it exits with no output. If I use `until`, it loops indefinitely but outputs `The exit status of first command 0, and the second command 1` which is when it should stop the loop. – user2328273 Oct 04 '16 at 20:34
  • The anonymous pipe will never fail unless one of the 2 processes die. In your case, it is unlikely to happen. `curl` will block for several minutes until server responds or until `--conect-timeout n` occurs. What you seem to need is `while ! curl --silent --connect-timeout 5000 http://192.168.1.2 | grep -q regular; do echo unable to connect to server after 5 seconds...retrying; done` – alvits Oct 04 '16 at 21:00
  • Typo error. Should be `--connect-timeout 5`. – alvits Oct 04 '16 at 21:09

2 Answers2

0

Although it's not really clear what kind of output is returned by the curl call, maybe you are looking for something like this:

curl --silent http://192.168.1.2 |while read line; do
  echo $line |grep -q regular || { err="true"; break }
done

if [ -z "$err" ]; then
  echo "..All lines OK"
else
  echo "..Abend on line: '$line'" >&2
fi
dheuvels
  • 91
  • 5
0

Figured it out. Just had to re-conceptualize it. I couldn't figure it out strictly with a while or until loop but creating an infinite loop and breaking out of it when the condition is met worked.

while true
    do curl http://192.168.1.2/api/queue | grep -q test
        case ${PIPESTATUS[*]} in
          "0 1")
              echo "Item is no longer in the queue."
              break;;
          "0 0")
              echo "Item is still in the queue. Trying again in 5 minutes."
              sleep 5m;;
          "7 1")
              echo "Server is unreachable. Trying again in 5 minutes."
              sleep 5m;;
          esac
   done
user2328273
  • 868
  • 3
  • 12
  • 22