【问题标题】:AWK pipe output from TTY to PHP从 TTY 到 PHP 的 AWK 管道输出
【发布时间】:2014-06-06 19:35:02
【问题描述】:

我有一个 tty 设备 (/dev/ttyUSB0),它偶尔会以Cycle 1: 30662 ms, 117.41 W 的形式输出一个字符串。我正在使用一个简单的 bash 脚本来处理它:

#!/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

test.php 脚本如下所示:

<?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);
?>

但是,kwhoutput.txt 仍然为空。为什么这不起作用?

【问题讨论】:

  • 回显 $line 会产生什么吗?
  • “偶尔”有多偶然?
  • @glennjackman 这取决于我们的能源使用情况,大约每 20-30 秒一次。 cat /dev/ttyUSB0 工作得很好。
  • 试试你的 while 循环而不用管道连接到 PHP。会发生什么?
  • 尝试od -c /dev/ttyUSB0 看看它是否包含您认为的内容。

标签: php linux bash debian tty


【解决方案1】:

awk 正在缓冲您的数据。使用fflush() 在每个输出行之后刷新缓冲区:

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

还要确保/dev/ttyUSB0 实际输出一行(以\n 结尾),而不仅仅是一串数据。

您还应该将您的 php 脚本修复为:

  1. 读取多行并逐行追加(否则,脚本将每隔一行跳过)。
  2. 了解如何在 php.ini 中附加到文件。读取整个文件,在内存中连接一个字符串,然后写入整个文件不是要走的路。

【讨论】:

  • 谢谢,这确实有效。但是,连接的设备在执行fflush() 时似乎会重置。每次您打开指向它的串行链接时,它通常都会执行此操作。我怎样才能防止这种情况发生?
  • 为防止反复打开设备,请按照答案中第 1 点所述修复您的 php 脚本。或者,使用 while read 循环为每一行反复调用 test.php| while IFS= read -r line; do php5 test.php &lt;&lt;&lt; "$line"; done
  • 我看不出 PHP 脚本会如何解决这个问题,因为设备是在 bash 脚本中打开的。
  • PHP读取一行退出时,awk也被强制退出,然后关闭设备。
  • 我能够使用stty -F /dev/ttyUSB0 -hupcl 修复设备重置。我已将 PHP 脚本更改为 while($line = fgets(STDIN)){ echo $line; $file = 'output.txt'; $current = file_get_contents($file); $current .= $line; file_put_contents($file, $current); } 我确实从串行设备获得了输出,但 output.txt 仍然为空。
猜你喜欢
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 2020-05-08
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多