RPi:Bash脚本,而读取循环在第一行

时间:2016-02-14 00:14:13

标签: bash while-loop

我最近买了一片收音机 - https://www.wirelessthings.net/slice-of-radio-wireless-rf-transciever-for-the-raspberry-pi,我用Raspbian连接到RPi的串口。

我有一个温度+湿度传感器连接到无线电切片并定期发送一串包含多个信息的字符,这些信息可以从串口(/ dev / ttyAMA0)在RPi中读取。

要阅读此信息并使用它,我决定编写一个Bash脚本。此信息与12个字符串串联传输,每个字符串始终以固定的字符集开头(在本例中为aSD)。

这个Bash脚本应该在无限循环中运行,以确保定期发送的所有信息都被捕获并按原样处理。

为此,以下小脚本正常工作:

    #!/bin/bash
    IFS='aSD'
    while read -r -n 12 char1 char2 char3 char4 char5
    do
    date=`/bin/date -u +%F@%X`
    echo $date
    echo  "1= ""$char1"
    echo  "2= ""$char2"
    echo  "3= ""$char3"
    echo  "4= ""$char4"
    echo  "5= ""$char5"
    done < /dev/ttyAMA0

并输出以下内容(每一行4是我需要的信息):

    2016-02-13@23:06:12
    1= 
    2= 
    3= 
    4= RHUM77.0-
    5= 
    2016-02-13@23:06:12
    1= 
    2= 
    3= 
    4= TEMP20.0-
    5= 
    2016-02-13@23:11:08
    1= 
    2= 
    3= 
    4= RHUM77.0-
    5= 
    2016-02-13@23:11:08
    1= 
    2= 
    3= 
    4= TEMP19.9-
    5= 
    2016-02-13@23:11:08
    1= 
    2= 
    3= 
    4= BATT3.32-
    5= 
    2016-02-13@23:11:08
    1= 
    2= 
    3= 
    4= 
    5= LEEPING-

然后,如果我运行以下脚本(我的简化版本):

    !/bin/bash
    log_file="/home/pi/logs/Temp_$(date +%Y%m%d).log"
    log_file_copy="/home/pi/logs/Temp_$(date +%Y%m%d)_copy.log"
    sensor="/home/pi/sensor"

    IFS='aSD'
    while read -r -n 12 char1 char2 char3 value char5
    do
    date=`/bin/date -u +%F@%X`
    msgid=$( /bin/echo $value | cut -c1-4 )
    echo $msgid
    if [ "$msgid" = "TEMP" ]; then

    #Write current temperature to log file
    log=`/bin/date -u +%F@%X`
    log+=" | Current Temperature: "
    temp=$( /bin/echo $value | cut -c5-8 )
    log+=$temp
    log+=" ºC"
    /bin/echo $log>>$log_file
    elif [ "$msgid" = "RHUM" ]; then

    #If log file backup still exists, start by deleting it
    if [ -f "$log_file_copy" ]; then
            /bin/rm $log_file_copy > /dev/null 2>&1 &
    fi
    #If log file already exists, start by creating a backup
    if [ -f "$log_file" ]; then
            /bin/mv $log_file $log_file_copy > /dev/null 2>&1 &
    fi

    #Write current relative humidity to log file
    log=`/bin/date -u +%F@%X`
    log+=" | Current Relative Humidity: "
    rhum=$( /bin/echo $value | cut -c5-8 ) 
    log+=$rhum
    log+=" %"
    /bin/echo $log>>$log_file
    elif [ "$msgid" = "BATT" ]; then

    #Write current battery voltage to log file
    log=`/bin/date -u +%F@%X`
    log+=" | Current Battery Voltage: "
    volt=$( /bin/echo $value | cut -c5-8 )
    if [ "$volt" != "LOW-" ]; then
            volt="LOW"
            log+=$volt
    else
            log+=$volt
            log+=" V"
    fi
    /bin/echo $log>>$log_file
    fi

    #Store values to display in website - personal.xively.com
    time=`/bin/date -u +%FT%XZ`
    if [ -n "$temp" ]; then
    /bin/echo "$time,$temp">>/home/pi/cosm/sensor/temperature/cosm.csv
    fi
    if [ -n "$rhum" ]; then
    /bin/echo "$time,$rhum">>/home/pi/cosm/sensor/humidity/cosm.csv
    fi
    if [ -n "$volt" ]; then
    /bin/echo "$time,$volt">>/home/pi/cosm/sensor/voltage/cosm.csv
    fi
    /bin/bash /home/pi/cosm/sensor/upload-cosm.sh > /dev/null 2>&1 &
    log=`/bin/date -u +%F@%X`
    log+=" | Values sent to xively.com"
    /bin/echo $log>>$log_file

    done < /dev/ttyAMA0

这就是它处理的所有内容:

    RHUM
    RHUM
    RHUM

如果我取出最后一段代码(将值发送到xively.com),它会显示(这就是我需要的):

    RHUM
    TEMP
    RHUM
    TEMP
    RHUM
    TEMP

我花了很多时间试图找出为什么循环不通过所有记录而只处理第一个记录。

任何人都可以解雇或提供任何可行的替代方案吗?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

为了清晰起见,我编辑了脚本,并根据您的第一组输出对我输入的内容进行了运行。我不认为循环跳过记录 - 也许输入与你的预期不符。下面的版本将原始数据捕获到文件中,因此您可以根据原始数据验证结果。

LEEPING-

一个重要的变化是该脚本不会改变IFS。 IFS的每个字符都是一个分隔符。一个很好的例子是当输入(大概)aSDSLEEPING-时char5的logger。相反,此脚本使用参数扩展的内置bash子字符串功能。

我省略了日志轮换,因为我建议你长期登录syslog。 int main() { int i=11; if (i > 100) { i = 100; } else if (i < 0) { i = 0; } cout << i << endl; } 命令将向syslog发送消息。在大多数系统上,这些日志已经定期轮换。