我一直在尝试向我的调制解调器发送一些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
但如果我将cat
更改为read
,则无法正常工作:
$ ./imei_checker.sh
Response was AT+CGSN
另外2个问题:
exec 3<&-
和exec 3>&-
似乎不起作用。我必须按 Ctrl + C 来
控制终端回来了。答案 0 :(得分: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>&-
现在我没有测试,因为我没有连接调制解调器(现在已经在宽带上使用了很长一段时间)但它应该关闭到你需要什么,如果不是确切的话。
答案 1 :(得分:1)
read
将描述符作为-u
后面的参数读取。有关详细信息,请参阅help read
。
答案 2 :(得分:1)
如果您想将各行变为变量,我建议将read
包裹到while
中:
while read -r RESPONSE <&3; do
echo "Response was $RESPONSE"
## e.g.:
[ "$RESPONSE" = "OK" ] && break
done
但是,如果您希望发回给您的“所有内容”都驻留在$RESPONSE
中,您可以这样做:
RESPONSE="$(cat <&3)"