1

I'm writing a simple script that reads line from a serial line and choose in which file save the string in function of the first char of the line.

My input is like this:

C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
B{"value":0.0,"setpoint":0.0,"isAuto":0}\n                                      
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n                                     
D{"value":0.0,"setpoint":0.0,"isAuto":0}\n                                     
...

And here the script I'm writing:

#!/bin/bash
stty -F /dev/ttyS1 115200 -echo
echo "Receiver is listening..."
while read -r line < /dev/ttyS1; do
  echo $line
  target=${line:0:1}
  echo $target
  if [ "$target" = "C" ]; then
    echo ${line#?} > /tmp/file1
  elif [ "$target" = "D" ]; then
    echo ${line#?} > /tmp/file2
  elif [ "$target" = "T" ]; then
    echo ${line#?} > /tmp/file3
  elif [ "$target" = "A" ]; then
    echo ${line#?} > /tmp/file4
  fi
done

but with the input above I see the following:

C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
uto":0}
u
C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
}
}
C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
uto":0}
u
C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
uto":0}
u
C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
:0}
:
C{"value":0.0,"setpoint":0.0,"isAuto":0}
C
":0}

Instead sending only one type of message, say "D", the output is correct:

D{"value":0.0,"setpoint":0.0,"isAuto":0}
D
D{"value":0.0,"setpoint":0.0,"isAuto":0}
D
D{"value":0.0,"setpoint":0.0,"isAuto":0}
D
D{"value":0.0,"setpoint":0.0,"isAuto":0}
D
D{"value":0.0,"setpoint":0.0,"isAuto":0}
D

There is something obviously wrong in my script?

Mark
  • 4,338
  • 7
  • 58
  • 120

1 Answers1

2

Try to use:

$ while read -r line; do ...; done < "${file}"

Instead of:

$ while read -r line < "${file}; do ...; done

This is why:

$ file="test.txt"; while read -r line; do echo "${line}"; sleep 1; done < "${file}"
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
B{"value":0.0,"setpoint":0.0,"isAuto":0}\n
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
D{"value":0.0,"setpoint":0.0,"isAuto":0}\n
$ file="test.txt"; while read -r line < "${file}"; do echo "${line}"; sleep 1; done
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
C{"value":0.0,"setpoint":0.0,"isAuto":0}\n
# Infinite loop...

You can read this to get more details one how to read a file or a command output line by line in bash.

Idriss Neumann
  • 3,760
  • 2
  • 23
  • 32