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

しかし、に変更catするとread、機能しません。

$ ./imei_checker.sh 
Response was AT+CGSN

さらに2つの質問:

  1. なぜ重複した出力が表示されるのですか?
  2. ファイルハンドルを正しく閉じるにはどうすればよいですか?exec 3<&-動作しexec 3>&- ないようです。ターミナルの制御を取り戻すには、Ctrl+を押す必要があります。C
4

3 に答える 3

2

readcat基本的にファイルの最後まで読み取ってエコーするのとは異なり、単一行のみを読み取ります。

バージョンの場合、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「モデム」からの応答がある場合とない場合の 2 つのサンプル実行:

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

個々の行を変数に入れたい場合は、次のようにラップreadすることをお勧めしますwhile:

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 に答える