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