0

I have been trying to write a python script that prints the first 10 lines of the CAN Bus data that is coming from a data pipe. The code works well when there is data in the pipe, but doesn't break out of the loop when no data.

#!/usr/bin/python2.7
import os
import re
with open('/var/run/regen/can0/rx', 'r') as pse:  #/var/run/regen/can0/rx is the data pipe
        count = 0
        for line in pse:
            if " " in line:
                break          #want to exit the loop when there is no data
            else:
                while count < 10:
                    for line in pse:
                        words = list(filter(None, re.split(r"[()\[\]\s]\s*", line)))
                        print(words)
                        count += 1
                        break
            break

Summary --- Works - Prints first 10lines when data is coming through the pipe Doesn't work - The loop doesn't break when there is no data in the pipe

I tried using a timer to exit the loop, but it doesn't work as well. The loop doesn't exit when the time given is complete.

#!/usr/bin/python2.7
import os
import time
t_end = time.time() + 0.2
while time.time() < t_end:
    with open('/var/run/regen/can0/rx', 'r') as pse:
    # --- remaining code ----

**Can anyone tell me how to check if a data pipe has any data incoming or not? **

Suprava
  • 69
  • 6
  • Did you try to check what is the value of `line` when there is no data in the pipe? – Barak Fatal Jan 10 '23 at 10:05
  • There is no output when there is no data. Its blank – Suprava Jan 10 '23 at 10:06
  • So I think it is just your condition is wrong - you are checking for a space in the data, not blank. Notice the difference between what you wrote: `" "`, and the empty string `""` – Barak Fatal Jan 10 '23 at 10:11
  • I tried this now. Still doesn't exit out of the loop.. maybe no data isn't equal to just a blank? – Suprava Jan 10 '23 at 10:34
  • Try to check what the type of `line` and if it equals something specific (perhaps `None`?) If you are familiar with `ipdb` package, you can use it to set a break in your code for debugging purposes. – Barak Fatal Jan 10 '23 at 11:33
  • Im printing the output on the terminal. When there is no data, there is no standard output. Not sure if `line` is `None`. Is there a way to check if a pipe has any incoming data or not? – Suprava Jan 10 '23 at 11:38
  • Does this answer your question? [How do I check if stdin has some data?](https://stackoverflow.com/questions/3762881/how-do-i-check-if-stdin-has-some-data) – Matthias Jan 10 '23 at 16:04
  • maybe this helps: https://stackoverflow.com/questions/39089776/python-read-named-pipe – Matthias Jan 13 '23 at 09:17

1 Answers1

0

See this thread.

Answer taken from there, this might work for you:

#!/usr/bin/python2.7
import os
import re
import sys

with open('/var/run/regen/can0/rx', 'r') as pse:  #/var/run/regen/can0/rx is the data pipe
    if not pse.isatty():
        count = 0
        for line in pse:
            words = list(filter(None, re.split(r"[()\[\]\s]\s*", line)))
            print(words)
            count += 1

This works to end the loop in my test file:

import sys

if not sys.stdin.isatty():
  for line in sys.stdin:
    sys.stdout.write(line)

When I run

echo "hello" | python pipe.py  # outputs: hello

however

python pipe.py  # outputs nothing, but ends the script

used to hang, but now the script finishes after I added the isatty()

However, since you open the pipe as a file, I think you can use traditional file reading logic. So I believe you shouldn't need the pse.isatty() line at all. I think this should work too:

#!/usr/bin/python2.7
import os
import re

with open('/var/run/regen/can0/rx', 'r') as pse:  #/var/run/regen/can0/rx is the data pipe
    count = 0
    for line in pse:
        words = list(filter(None, re.split(r"[()\[\]\s]\s*", line)))
        print(words)
        count += 1

I skipped the while and extra for loop, that was hanging the script when I tried.

Matthias
  • 3,160
  • 2
  • 24
  • 38
  • Hi. Thanks for the comment. I tried your script but it breaks out in all conditions. As in, it breaks out when there is incoming data in the pipe & does the same when there is no data as well. Is there a way to check if the data pipe has incoming stream of data? i tried methods from the link you have attached, still it doesn't work. – Suprava Jan 11 '23 at 06:40
  • oh right.. that's because my solution is garbage XD I'm just checking stdin, but you are not using stdin.. I modified it, try it now – Matthias Jan 11 '23 at 09:02
  • I'm assuming you run your script periodically to check the pipe in my answer, but even if that's not the case, hopefully it still works then with the isatty line – Matthias Jan 11 '23 at 09:15
  • Hey. Thanks for the edit. But, it still doesn't work ( Doesn't exit the loop when there is no data). I think the data pipe is waiting for the input before proceeding with any execution. – Suprava Jan 13 '23 at 05:16
  • I'm gonna need more info about your setup then, how is data piped to `/var/run/regen/can0/rx`? I need to be able to reproduce the issue – Matthias Jan 13 '23 at 08:58
  • also, how do you run your script? (the one you posted) how is it scheduled? – Matthias Jan 13 '23 at 09:07