Страница 1 из 4

[РЕШЕНО] AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 14:04
booBot
asterisk v1.8.32.3

При выполнении сценария из dialplan'а спомощью AGI вижу сообщение об ошибке: write() returned error: Broken pipe

Код: Выделить всё

  == Using SIP RTP CoS mark 5
    -- Executing [79012345678@phones:1] Set("SIP/025-00000026", "OP=xxxx:yyyy") in new stack
    -- Executing [79012345678@phones:2] Set("SIP/025-00000026", "AGISIGHUP=no") in new stack
    -- Executing [79012345678@phones:3] AGI("SIP/025-00000026", "mnp_chk-v2.sh,9012345678") in new stack
    -- Launched AGI Script /var/lib/asterisk/agi-bin/mnp_chk-v2.sh
<SIP/025-00000026>AGI Tx >> agi_request: mnp_chk-v2.sh
<SIP/025-00000026>AGI Tx >> agi_channel: SIP/025-00000026
<SIP/025-00000026>AGI Tx >> agi_language: en
<SIP/025-00000026>AGI Tx >> agi_type: SIP
<SIP/025-00000026>AGI Tx >> agi_uniqueid: 1463100693.38
<SIP/025-00000026>AGI Tx >> agi_version: 1.8.32.3
<SIP/025-00000026>AGI Tx >> agi_callerid: 025
<SIP/025-00000026>AGI Tx >> agi_calleridname: 025
<SIP/025-00000026>AGI Tx >> agi_callingpres: 0
<SIP/025-00000026>AGI Tx >> agi_callingani2: 0
<SIP/025-00000026>AGI Tx >> agi_callington: 0
<SIP/025-00000026>AGI Tx >> agi_callingtns: 0
<SIP/025-00000026>AGI Tx >> agi_dnid: 79012345678
<SIP/025-00000026>AGI Tx >> agi_rdnis: unknown
<SIP/025-00000026>AGI Tx >> agi_context: phones
<SIP/025-00000026>AGI Tx >> agi_extension: 79012345678
<SIP/025-00000026>AGI Tx >> agi_priority: 3
<SIP/025-00000026>AGI Tx >> agi_enhanced: 0.0
<SIP/025-00000026>AGI Tx >> agi_accountcode: 
<SIP/025-00000026>AGI Tx >> agi_threadid: 1989260592
<SIP/025-00000026>AGI Tx >> agi_arg_1: 9012345678
<SIP/025-00000026>AGI Tx >> 
<SIP/025-00000026>AGI Rx << SET VARIABLE OP 4968
<SIP/025-00000026>AGI Tx >> 200 result=1
[May 13 00:51:35] ERROR[4971]: utils.c:1343 ast_carefulwrite: write() returned error: Broken pipe
    -- <SIP/025-00000026>AGI Script mnp_chk-v2.sh completed, returning 0
    -- Executing [79012345678@phones:4] NoOp("SIP/025-00000026", "4968") in new stack
    -- Executing [79012345678@phones:5] GotoIf("SIP/025-00000026", "0?:not-a-megafon") in new stack
    -- Goto (phones,79012345678,9)
    -- Executing [79012345678@phones:9] NoOp("SIP/025-00000026", "79012345678 is someone else's subscriber, routing via Youmagic") in new stack
    -- Executing [79012345678@phones:10] Dial("SIP/025-00000026", "SIP/+79012345678@youmagic,60,r") in new stack
  == Using SIP RTP CoS mark 5
    -- Called SIP/+79012345678@youmagic
  == Spawn extension (phones, 79012345678, 10) exited non-zero on 'SIP/025-00000026'
OpenWrt*CLI> 
Вот запускаемый сценарий:

Код: Выделить всё

root@OpenWrt:~# cat /var/lib/asterisk/agi-bin/mnp_chk-v2.sh
#!/bin/sh
while read VAR && [ -n ${VAR} ] ; do : ; done
read "GET VARIABLE OP"
USERAGENT='asterisk v1.8.32.3'
echo -n "SET VARIABLE OP $(wget -O - -q -T 5 -U "$USERAGENT" "http://rosreestr.и так далее...
read RESPONSE
Попытку прочитать отклик (вроде бы) делаю...


Вот исполняемый при этом dialplan:

Код: Выделить всё

[out]
exten   =>_79XXXXXXXXX,1,Set(OP=xxxx:yyyy)
same    => n,AGI(mnp_chk-v2.sh,${EXTEN:1})
same    => n,NoOp(${OP})
same    => n,GotoIf($[${OP:-4:4}=2961]?:not-a-megafon)
same    => n,NoOp(${EXTEN} is MegaFon's subscriber, routing via MultiFon)
same    => n,Dial(SIP/${EXTEN}@multifon,30,r)
same    => n,Hangup()
same    => n(not-a-megafon),NoOp(${EXTEN} is someone else's subscriber, routing
; Note: Youmagic requires numbers prepended with "+"
same    => n,Dial(SIP/+${EXTEN}@youmagic,60,r)
same    => n,Hangup()
Как и тут, пробовал AGISIGHUP=no, AGISIGHUP=yes - не влияет.
Судя по всему, это из-за

Код: Выделить всё

<SIP/025-00000026>AGI Rx << SET VARIABLE OP 4968
<SIP/025-00000026>AGI Tx >> 200 result=1
Можно ли это исправить? Хотелось бы разобраться досконально.

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 15:00
zzuz
Что это возвращается из "так далее" ?
SET VARIABLE OP 4968

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 15:21
booBot
Из "итакдалее" возвращается четырёхзначный код обслуживающего GSM-оператора.
Показанное в примере его значение - правильное.

Что надо сделать в сценарии (и желательно - как?), чтобы по окончании его работы упомянутая ошибка не возникала?

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 15:35
zzuz
read RESPONSE
что вы хотите получить и зачем это вам?

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 15:38
booBot
Это попытка прочитать ответ перед выходом из сценария, именно так я понял эту рекомендацию.

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 16:02
BorisTheBlade
добавление sleep .1 в конце скрипта обычно помогает.

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 17:36
booBot
Спасибо.

Моя попытка "прочитать ответ перед завершением работы" сценария - read RESPONSE - взята из Quick-Start-примера в главе 21 Asterisk Gateway Interface (AGI). Оттуда же взята и "консумация" всех переменных, передаваемых сценарию.

Подозреваю, что RESPONSE отнюдь не то же самое, что AGI пытается передать мне тут:

Код: Выделить всё

<SIP/025-00000026>AGI Tx >> 200 result=1
Если бы мне действительно был нужен ответ "сверху", как бы я должен был получать этот result?

Re: AGI: write() returned error: Broken pipe

Добавлено: 13 май 2016, 22:07
booBot
Попробовал в конце сценария:

Код: Выделить всё

...
sleep 1s
read RESPONSE
sleep 1s
exit 0
Не помогло убрать ошибку.

Re: AGI: write() returned error: Broken pipe

Добавлено: 14 май 2016, 09:18
virus_net
1. Broken pipe возникает из-за неожиданного принта. Это может быть некое сообщение от исполняемого бинаря и пр.
2. В скриптах необходимо всегда указывать абсолютные пути до исполняемых бинарей, а не относительные.
В данном случае как минимум необходимо:
  • - указать абсолютный путь до wget
    - точно понимать что возвращает исполнение wget и нет ли там, например, переноса строки

Re: AGI: write() returned error: Broken pipe

Добавлено: 14 май 2016, 12:14
booBot
Спасибо.
Так как не был уверен, что на OpenWrt реализация echo соблюдает ключ "-n", переделал на рекомендуемый способ (printf).
Вот нынешняя версия сценария, представленная полностью:

Код: Выделить всё

root@OpenWrt:~# cat /var/lib/asterisk/agi-bin/mnp_chk-v2.sh
#!/bin/ash
# MNP checking script.
# AGI expects it to be in /var/lib/asterisk/agi-bin/
# The script accepts a 10-digit number
# The OP variable is set to YYYY[:ZZZZ] string,
# where YYYY is the original serving operator code,
# and ZZZZ is a "moved to" operator code if the subscriber
# has done MNP. If no MNP move was done - only YYYY is returned.

while read VAR && [ -n ${VAR} ] ; do : ; done
USERAGENT='asterisk v1.8.32.3'
printf "SET VARIABLE OP $(/usr/bin/wget -O - -q -T 5 -U "$USERAGENT" "http://rosreestr.subnets.ru/index.php?get=num&num=$1" |/bin/grep -o 'rID: [0-9]\+' |/bin/sed 's/rID: //' |/bin/sed 'N;s/\n/:/')"
read RESPONSE
sleep 1s
exit 0
root@OpenWrt:~# 
Ошибка осталась.