通过 Bash 从 Cisco C40 获取输出
Getting Output from Cisco C40 via Bash
背景
我们有一些 Cisco C40,我正试图通过 bash 实现自动化(尽管我愿意接受其他选择)。我需要登录它,拨一个 IP,取回返回的呼叫 ID,然后使用该 CallID 向远端发送 DTMF 音。我能够完成大约 90% 的过程,但出于某种原因,使用 SSH 时并没有返回使用交互式会话时返回的所有文本。
交互式Shell示例:
login as: admin
Using keyboard-interactive authentication.
Password:
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
xConfiguration Audio Volume: 0
** end
OK
xCommand Dial Number: FAR_END_IP
OK
*r DialResult (status=OK):
CallId: 73
ConferenceId: 44
** end
非交互式Shell 示例
没有 ssh -T
或 ssh -t -t
选项
这发生在 call-init-step1.txt 除了要挂断的 bye
之外还包含 xConfiguration Audio Volume: 0
和 xCommand Dial Number: FAR_END_IP
。
[user@controlserver C40]$ cat call-init-step1.txt | ssh admin@cisco_codec
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
** end
OK
OK
我在这里缺少的是带有
的块
*r DialResult (status=OK):
CallId: 73
ConferenceId: 44
** end
这样我就可以为 CallID
解析它,然后用它来发送下一个命令。
带有 ssh -T
或 ssh -t -t
选项
一些线程建议使用 ssh -T
或 ssh -t -t
,在这种情况下似乎没有帮助,下面是输出。
[user@controlserver C40]$ cat call-init-step1.txt | ssh -T admin@cisco_codec
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
** end
OK
OK
和
[user@controlserver C40]$ cat call-init-step1.txt | ssh -t -t admin@cisco_codec
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
** end
OK
OK
问题
任何关于如何获得丢失的 DialResult
块的见解将不胜感激。
编辑:我还应该提到,最终命令 cat call-init-step1.txt | ssh admin@cisco_codec
将被重定向到一个文件,以便在我的脚本中进一步解析,这意味着它可能看起来像 cat call-init-step1.txt | ssh -t -t admin@cisco_codec > results.txt
然后被解析.
编辑 2:构建我正在使用的 full API guide is found here
编辑 2.5:expect
的尝试
根据@MarkSetchell 的建议,我们继续编写了一个半功能 expect 脚本,如下所示:
#!/usr/bin/expect
spawn ssh admin@cisco_codec
expect "*r Login successful"
send "xConfiguration Audio Volume: 0"
expect "OK"
send "xCommand Dial Number: FAR_END_IP"
expect "** end"
结果如下:
[user@controlserver C40]$ expect expect-call
spawn ssh admin@cisco_codec
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
xConfiguration Audio Volume: 0xCommand Dial Number: FAR_END_IPxConfiguration Audio Volume: 0xCommand Dial Number: FAR_END_IP
似乎有一些方法可以解决这个问题,如果我必须坚持使用 bash,似乎使用正确编写的 except
脚本将是可行的方法。那是说 a Reddit post I'd made suggested XML. Using XML had crossed my mind but neither I nor the folks I immediately had to help me were super well versed with how to go about this but with an incredibly helpful post 上的某个人,我正在使用 Python 和 XML。
最终产品看起来像这样:
#!/usr/bin/env python
import time
import requests
from lxml.etree import fromstring, Element, tostring
def putxml_request(xml, **kwargs):
return requests.post(
'http://HOSTNAME/putxml',
auth=('USER', 'PASSWORD'),
data=xml.format(**kwargs)).content
def xconfiguration_request(*path, **keys_and_values):
root = Element('Configuration')
parent = root
for level in path:
current = Element(level)
parent.append(current)
parent = current
for k, v in keys_and_values.iteritems():
node = Element(k)
node.text = str(v)
current.append(node)
xml = tostring(root, pretty_print=True)
return putxml_request(xml)
xconfiguration_request('Audio', Volume=0)
DIAL = '''\
<Command>
<Dial>
<Number>{number}</Number>
<Protocol>{protocol}</Protocol>
</Dial>
</Command>'''
outcome = putxml_request(
DIAL, number='XXX', protocol='Sip')
callid = fromstring(outcome).xpath('//CallId')[0].text
# this gives it some time for the call to connect
time.sleep(10)
DTMFSEND = '''\
<Command>
<DTMFSend>
<CallId>{callid}</CallId>
<DTMFString>{dtmf}</DTMFString>
</DTMFSend>
</Command>'''
outcome = putxml_request(DTMFSEND, callid=callid, dtmf='1234')
status = fromstring(outcome).xpath('//DTMFSendResult')[0].attrib['status']
if status != 'OK':
print('bad')
else:
print('sent dtmf')
最终我安排了这个脚本来发起呼叫(通过 cron),然后编写了一个非常相似的脚本来使用 DisconnectAll
挂断电话。
我希望这对某人有所帮助,并感谢 Reddit 上的 /u/omgdave(我提供了一个机会来回答这个问题,但没有被接受)提供的帮助。
背景
我们有一些 Cisco C40,我正试图通过 bash 实现自动化(尽管我愿意接受其他选择)。我需要登录它,拨一个 IP,取回返回的呼叫 ID,然后使用该 CallID 向远端发送 DTMF 音。我能够完成大约 90% 的过程,但出于某种原因,使用 SSH 时并没有返回使用交互式会话时返回的所有文本。
交互式Shell示例:
login as: admin
Using keyboard-interactive authentication.
Password:
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
xConfiguration Audio Volume: 0
** end
OK
xCommand Dial Number: FAR_END_IP
OK
*r DialResult (status=OK):
CallId: 73
ConferenceId: 44
** end
非交互式Shell 示例
没有 ssh -T
或 ssh -t -t
选项
这发生在 call-init-step1.txt 除了要挂断的 bye
之外还包含 xConfiguration Audio Volume: 0
和 xCommand Dial Number: FAR_END_IP
。
[user@controlserver C40]$ cat call-init-step1.txt | ssh admin@cisco_codec
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
** end
OK
OK
我在这里缺少的是带有
的块*r DialResult (status=OK):
CallId: 73
ConferenceId: 44
** end
这样我就可以为 CallID
解析它,然后用它来发送下一个命令。
带有 ssh -T
或 ssh -t -t
选项
一些线程建议使用 ssh -T
或 ssh -t -t
,在这种情况下似乎没有帮助,下面是输出。
[user@controlserver C40]$ cat call-init-step1.txt | ssh -T admin@cisco_codec
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
** end
OK
OK
和
[user@controlserver C40]$ cat call-init-step1.txt | ssh -t -t admin@cisco_codec
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
** end
OK
OK
问题
任何关于如何获得丢失的 DialResult
块的见解将不胜感激。
编辑:我还应该提到,最终命令 cat call-init-step1.txt | ssh admin@cisco_codec
将被重定向到一个文件,以便在我的脚本中进一步解析,这意味着它可能看起来像 cat call-init-step1.txt | ssh -t -t admin@cisco_codec > results.txt
然后被解析.
编辑 2:构建我正在使用的 full API guide is found here
编辑 2.5:expect
的尝试
根据@MarkSetchell 的建议,我们继续编写了一个半功能 expect 脚本,如下所示:
#!/usr/bin/expect
spawn ssh admin@cisco_codec
expect "*r Login successful"
send "xConfiguration Audio Volume: 0"
expect "OK"
send "xCommand Dial Number: FAR_END_IP"
expect "** end"
结果如下:
[user@controlserver C40]$ expect expect-call
spawn ssh admin@cisco_codec
Welcome to XXX
TANDBERG Codec Release TC7.1.1.168aadf
SW Release Date: 2014-04-11
*r Login successful
OK
xConfiguration Audio Volume: 0xCommand Dial Number: FAR_END_IPxConfiguration Audio Volume: 0xCommand Dial Number: FAR_END_IP
似乎有一些方法可以解决这个问题,如果我必须坚持使用 bash,似乎使用正确编写的 except
脚本将是可行的方法。那是说 a Reddit post I'd made suggested XML. Using XML had crossed my mind but neither I nor the folks I immediately had to help me were super well versed with how to go about this but with an incredibly helpful post 上的某个人,我正在使用 Python 和 XML。
最终产品看起来像这样:
#!/usr/bin/env python
import time
import requests
from lxml.etree import fromstring, Element, tostring
def putxml_request(xml, **kwargs):
return requests.post(
'http://HOSTNAME/putxml',
auth=('USER', 'PASSWORD'),
data=xml.format(**kwargs)).content
def xconfiguration_request(*path, **keys_and_values):
root = Element('Configuration')
parent = root
for level in path:
current = Element(level)
parent.append(current)
parent = current
for k, v in keys_and_values.iteritems():
node = Element(k)
node.text = str(v)
current.append(node)
xml = tostring(root, pretty_print=True)
return putxml_request(xml)
xconfiguration_request('Audio', Volume=0)
DIAL = '''\
<Command>
<Dial>
<Number>{number}</Number>
<Protocol>{protocol}</Protocol>
</Dial>
</Command>'''
outcome = putxml_request(
DIAL, number='XXX', protocol='Sip')
callid = fromstring(outcome).xpath('//CallId')[0].text
# this gives it some time for the call to connect
time.sleep(10)
DTMFSEND = '''\
<Command>
<DTMFSend>
<CallId>{callid}</CallId>
<DTMFString>{dtmf}</DTMFString>
</DTMFSend>
</Command>'''
outcome = putxml_request(DTMFSEND, callid=callid, dtmf='1234')
status = fromstring(outcome).xpath('//DTMFSendResult')[0].attrib['status']
if status != 'OK':
print('bad')
else:
print('sent dtmf')
最终我安排了这个脚本来发起呼叫(通过 cron),然后编写了一个非常相似的脚本来使用 DisconnectAll
挂断电话。
我希望这对某人有所帮助,并感谢 Reddit 上的 /u/omgdave(我提供了一个机会来回答这个问题,但没有被接受)提供的帮助。