У меня есть USB-модем RNDIS, который разрешает AT-команды через порт telnet (5510). Я хочу использовать его для чтения и отправки SMS-сообщений из скрипта. Я использовал вариант аналогичного вопроса, опубликованного здесь, но я использую socat вместо netcat.
#!/bin/sh
echo -e $@
IFS=$'\n'
while read line; do
echo $line >&3
if [ "${line::2}" = "OK" ] || [ "${line::5}" = "ERROR" ] ; then
break
fi
done
smsio() {
response=$(3>&1 socat -T 2 exec:"./atread.sh '$1'" tcp:xxx.xxx.xxx.xxx:5510,crlf)
... (some other code to check for a timeout or broken pipe)
}
smsio "AT+CMGF=1"
.Это работает очень хорошо, если параметр не содержит специальных символов, а именно:
smsio 'AT+CMGL = "ALL"'
для чтения всех SMS-сообщенийsmsio 'AT+CMGS = "123456789"' ; smsio "Text Message\x1A"
для отправки SMSЯ пытался экранировать специальный символ, используя обратную косую черту (\") и/или добавляя двойные кавычки ("".."), но похоже, что socat удаляет все специальные символы перед вызовом сценария exec. Любые предложения, как получить эти специальные символы через socat?
PS: я временно обошел проблему с помощью замены символов (т.е. используя ! for " в строке параметров, затем используя tr '!' '"'
в atread.sh, но я ищу более элегантное решение.
Извините, да, используя пепел. Он работает на маршрутизаторе (OpenWRT), поэтому не может использовать ничего такого тяжелого, как Python. Я добавил несколько отпечатков трассировки как к вызову, так и к вызывающему абоненту и попробовал различные варианты. Я ожидал, что специальный символ появится, когда я использовал обратную косую черту. Я буду исследовать coproc и tcpdump.
Парсер адресов Socats специально интерпретирует несколько символов, например:
: , ! " ' \ ( [ {
Вы должны экранировать их обратной косой чертой. Обратите внимание, что вам также необходимо экранировать несколько специальных символов, включая \, из синтаксического анализатора оболочки.
Используйте опции -d -d -d -d, чтобы увидеть параметры, которые socat получает и использует; попробуйте что-то вроде
socat -u /tmp/nonexistingdir/x\\\\x -
чтобы увидеть в сообщении об ошибке, что осталось от специальных символов, когда socat выполняет последний системный вызов.
Опция -d -d -d -d действительно помогла. Позвольте мне посмотреть, что было передано socat. Я был очень близок. Для работы требуется 3 escape-последовательности (обратная косая черта). Так что призыв читать смс-сообщения - это смс smsio 'AT+CMGL=\\\"ALL\\\"'
.
Сообщение об отправке было немного сложнее: smsio 'AT+CMGS=\\\"123456789\\\"' ; smsio "Text Message"'\\\\x1A'
Спасибо за помощь.
Проверьте свой скрипт с помощью shellcheck. Это вообще какой-то странный подход. И вы пометили bash и ash - какой из них вы используете? В любом случае, используйте
coproc socat - tcp:...
и общайтесь с coproc. И рассмотрите возможность использования python. Написать это в Bash будет сложнее. Для передачи правильно цитируемых значений используйтеprintf "%q"
или просто используйте переменные среды.it appears that socat is stripping
Как "оказывается"? Вы его отладили? Запуститеtcpdump
и посмотрите, что отправляется.