0

I have a weird situation where Bash doesn't seem to be assigning one of my variables correctly, or it might be to do with pipes. I'm honestly not sure. Here's the code:

test=0

if [ "$#" -ne 4 ]; then
    echo "Error: You have passed an incorrect number of parameters" > client.pipe
    test=1 

if [ $test -eq 1 ]; then <-------THIS SOMETIMES DOESN'T EXECUTE
    echo "end_result" > client.pipe
    exit 1

What's going on here is this is a server script for a command: 'select'.

The select command takes in 4 parameters: an id (to tell it which pipe to output messages to), a database name, a table name, and then a string of column ids.

At the other end of the client pipe, the client script is listening for messages, and if it receives 'end_result' it stops listening. As you can see, no matter what happens 'end_result' should get sent back to the pipe and printed by the client script, but sometimes it doesn't happen, and I get stuck in an infinite while loop. Here's the client script so you can see where the 'listening' is happening.

     while true; do
        read message < client.pipe
           if [ "$message" == "end_result" ]; then
              echo $message 
              break
           else
              echo $message
           fi
       done

If I pass in the incorrect number of parameters to the first script, it prints out 'Error: you have passed an incorrect num of parameters' to the pipe, but then sometimes it doesn't assign 1 to test, and it doesn't then send 'end_result' to the pipe and exit. I can't really see what the issue is, and as I've said it works probably 7 times out of 10... I can get around the issue by having the parent script send 'end_result' to the client, but it's a bit of a hack.

I'd really appreciate it if anyone could see what the issue is, and I'm happy to provide more info about the code if required.

Many thanks, R

EDIT:

I'm almost certain the problem is to do with reading from the client pipe and that while loop, as though something were getting stuck in the pipe...

Raph117
  • 3,441
  • 7
  • 29
  • 50
  • Is there any chance you can reduce this to a (much smaller) [mcve]? This is very much code to go through. – Benjamin W. Dec 03 '18 at 19:41
  • Hi Ben, sure, I'll edit it now – Raph117 Dec 03 '18 at 19:42
  • Also, without looking at it more closely, but seeing "variable assigning" and "pipe", might it be anything to do with https://mywiki.wooledge.org/BashFAQ/024? – Benjamin W. Dec 03 '18 at 19:43
  • 1
    Hi Ben, I've done some editing. I think what's going on is that the client is looping and listening but sometimes the loop and what's being passed into the pipe somehow miss one another? – Raph117 Dec 03 '18 at 19:47
  • 2
    You probably do not want to be re-opening the pipe on each iteration of the while loop. Replace `while true; do read message < client.pipe....` with `while true; do read message; ... done < client.pipe` – William Pursell Dec 03 '18 at 19:49
  • Thanks William I'll try now – Raph117 Dec 03 '18 at 19:51
  • @WilliamPursell that worked! I had to do one more bit of error checking to make sure nothing outputted if there was nothing in the pipe but otherwise great! How do I mark this as answered? – Raph117 Dec 03 '18 at 19:57

1 Answers1

0

This was the solution, provided by @WilliamPursell:

 while true; do
        read message 
           if [ "$message" == "end_result" ]; then
              echo $message 
              break
           else
              echo $message
           fi
       done < client.pipe
Raph117
  • 3,441
  • 7
  • 29
  • 50
  • The idiomatic way to read lines from a file is described in [this Q&A](https://stackoverflow.com/questions/10929453) and in [BashFAQ/001](https://mywiki.wooledge.org/BashFAQ/001): `while IFS= read -r line; do ... done < client.pipe` – Benjamin W. Dec 03 '18 at 21:37