2

我一直在尝试向我的调制解调器发送一些 AT 命令,并希望将响应捕获到变量中。这是我的代码:

exec 3<>/dev/ttyUSB3

echo -e "AT+CGSN\n" >&3

cat <&3
#read -r RESPONSE <&3
#echo "Response was $RESPONSE"

exec 3<&-
exec 3>&-

结果:

$ ./imei_checker.sh 
AT+CGSN


356538041935676



OK

AT+CGSN


356538041935676



OK

但是,如果我更改catread,它将不起作用:

$ ./imei_checker.sh 
Response was AT+CGSN

还有2个问题:

  1. 为什么它显示重复的输出?
  2. 如何正确关闭文件句柄?exec 3<&-并且exec 3>&- 似乎不起作用。我必须按Ctrl+C才能重新控制终端。
4

3 回答 3

2

read只会读取一行,不像cat它基本上会读取并回显直到文件结束。

对于一个read版本,您最好不要阅读超时,直到您获得OK(并存储任何包含大量数字的行)。

我想你会发现不是关闭 3 号文件句柄会阻止事情——它更有可能是cat继续读取/回显直到文件结束事件没有发生。

如果您只输入以下内容,您可以确定这一点:

echo XYZZY

紧接在闭幕词之前exec。如果它还在cat,你将永远看不到它。

因此,使用循环read版本也可能会解决这个问题。


例如,以下是您可以使用read标准输入执行此操作的方法:

#!/bin/bash

NUM=
while true ; do
    read -p "> " -t 10 -r RESP <&0
    if [[ $? -ge 128 ]] ; then RESP=OK ; fi
    echo "Entered: $RESP"
    if [[ $RESP = OK ]] ; then break ; fi

    if [[ $RESP =~ ^[0-9] ]] ; then NUM=$RESP ; fi
done

echo "Finished, numerics were: '$NUM'"

它使用 的超时功能read来检测是否没有更多输入(将输入设置OK为以强制循环退出)。如果你那之前得到一个OK,它无论如何都会正常退出,超时只是为了迎合调制解调器没有按预期应答的可能性。

该数字最初设置为空,但被“调制解调器”中以数字开头的任何行覆盖。

两个示例运行,有和没有OK来自“调制解调器”的响应:

pax> ./testprog.sh
> hello
Entered: hello
> 12345
Entered: 12345
> OK
Entered: OK
Finished, numerics were: '12345'

pax> ./testprog.sh
> hello
Entered: hello
> now we wait 10 secs
Entered: now we wait 10 secs
> Entered: OK
Finished, numerics were: ''

将其转换为与您的调制解调器设备类似的东西并不难(read <&3或者read -u3可以正常工作)。


这基本上会转化为您的环境:

exec 3<>/dev/ttyUSB3
echo -e "AT+CGSN\n" >&3
NUM=
while true ; do
    read -t 10 -r RESP <&3
    if [[ $? -ge 128 ]] ; then RESP=OK ; fi
    echo "Entered: $RESP"
    if [[ $RESP = OK ]] ; then break ; fi
    if [[ $RESP =~ ^[0-9] ]] ; then NUM=$RESP ; fi
done
echo "Finished, numerics were: '$NUM'"
exec 3<&-
exec 3>&-

现在我还没有测试过,因为我没有连接调制解调器(已经使用宽带很长一段时间了),但它应该接近你需要的,如果不准确的话。

于 2012-08-17T04:07:07.100 回答
1

read将要读取的描述符作为-u. 详情请参阅help read

于 2012-08-17T03:47:27.493 回答
1

如果您想将各个行放入变量中,我建议您将其包装readwhile

while read -r RESPONSE <&3; do
  echo "Response was $RESPONSE"
  ## e.g.:
  [ "$RESPONSE" = "OK" ] && break
done

但是,如果您希望发送回给您的“所有内容”都驻留在其中,$RESPONSE您可以这样做:

RESPONSE="$(cat <&3)"
于 2012-08-17T04:13:55.290 回答