Search code examples
phplinuxbashdebiantty

AWK pipe output from TTY to PHP


I have a tty device (/dev/ttyUSB0), which occasionally outputs a string in the form of Cycle 1: 30662 ms, 117.41 W. I'm using a simple bash script to process it:

#!/bin/sh
stty -F /dev/ttyUSB0 57600

cd /home/pi
while true; do
 cat /dev/ttyUSB0 | awk '{ print $0 > "/dev/stderr"; if (/^Cycle/) { print "update kWh.rrd N:" $5 } }' | php5 test.php
 sleep 1
done

The test.php script looks like this:

<?php
stream_set_blocking(STDIN, 0);
$line = trim(fgets(STDIN));

$file = 'kwhoutput.txt';
$current = file_get_contents($file);
$current .= $line;
file_put_contents($file, $current);
?>

however, the kwhoutput.txt remains empty. Why is this not working?


Solution

  • awk is buffering your data. Use fflush() to flush the buffers after each output line:

    awk '{
      print $0 > "/dev/stderr"; 
      if (/^Cycle/) { 
        print "update kWh.rrd N:" $5;
        fflush(); 
      } 
    }'  < /dev/ttyUSB0  | php5 test.php
    

    Also make sure that /dev/ttyUSB0 actually outputs a line (terminated by \n), and not just a string of data.

    You should also fix up your php script to:

    1. Read multiple lines and append them one by one (otherwise, the script will skip every other line).
    2. Find out how to append to a file in php. Reading the whole file, concatenating a string in memory, then writing the whole file is not the way to go.