Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read two files in real time

Tags:

bash

If I have two devices connected via USB (in linux) and would like to read them both at the same time. Essentially, they never terminate, but I want to read them whenever they read a line (each line ends with \r\n).

Here is what it would look like in Python:

from threading import Thread

usb0 = open("/dev/ttyUSB0", "r")
usb1 = open("/dev/ttyUSB1", "r")

def read0():
    while True: print usb0.readline().strip()

def read1():
    while True: print usb1.readline().strip()

if __name__ == '__main__':
    Thread(target = read0).start()
    Thread(target = read1).start()

Is there any way to do that in bash. I know you can do this:

while read -r -u 4 line1 && read -r -u 5 line2; do
  echo $line1
  echo $line2
done 4</dev/ttyUSB0 5</dev/ttyUSB1

That, however, actually cuts off part of my line every couple times a second. I am really more curious if this is possible and don't really need it since it is pretty easy with threading in a modern programming language like Java or Python.

like image 202
dylnmc Avatar asked Mar 19 '23 02:03

dylnmc


1 Answers

It is not possible to start a thread in bash but you can fork off two background jobs for the reading. You need to spread the read actions into two separate while constructs and put them into background using the ampersand operator &:

#!/bin/bash

# Make sure that the background jobs will 
# get stopped if Ctrl+C is pressed
trap "kill %1 %2; exit 1" SIGINT SIGTERM

# Start a read loop for both inputs in background
while IFS= read -r line1 ; do
  echo "$line1"
  # do something with that line ...
done </dev/ttyUSB0 &

while IFS= read -r line2 ; do
  echo "$line2"
  # do something with that line ...
done </dev/ttyUSB1 &

# Wait for background processes to finish
wait %1 %2
echo "jobs finished"
like image 158
hek2mgl Avatar answered Apr 01 '23 07:04

hek2mgl