跳转至主要内容

上周(好吧,是上周我开始写这个的时候),我们CAC出现了一个问题,有人想写一个运行telnet的命令宏来登录系统并执行一些命令,比如命令宏test.cm登录远程主机并执行foo.cm命令宏。

&attach_input                 
telnet 192.168.77.128
密码
foo.cm

图1 - telnet命令巨集test.cm

display_line display_system_usage.                     
display_system_usage
display_line netstat -statistics -protocol tcp
netstat -statistics
display_line analyze_system -request_line 'stcp_meters -all -long' -quit
analyze_system -request_line 'stcp_meters' -quit

图2 - foo.cm

 

遗憾的是telnet没有设计成在命令宏中执行,它失败了。

检验      
telnet: fatal error - tcgetattr failed(失败)
测试的第3行出错。
command_processor:未找到对象,密码在命令宏
     %azvos#m17_mas>SysAdmin>Noah_Davids>test.cm。

图3 - 执行test.cm失败

 

然而,有几种方法可以实现自动登录到远程主机,然后执行命令。

send_cmds.c。

我之前写了一个程序,它可以连接到telnet服务器,发送字符串,并解析输出。脚本语言很简单,但对于简单的事情来说,它可以很好地工作。源代码和更多的例子可以在这里找到。

脚本基本上是一个发送字符串,后面是一个等待字符串。当看到等待字符串时,脚本就会进入下一行,正如我所说,非常简单。脚本是有参数的,在图4中,我用arg0作为密码,所以我的密码并没有存储在脚本中。脚本的执行情况如下图5。为了节省空间,我截断了每个命令的输出。你会注意到,在我将终端类型设置为ascii之前,字符定位字符串中的非控制字符都会显示出来。

//登录        
/login nd/Password?
/arg0/ready
/set_terminal_parameters -terminal_type ascii -pause_lines 0/ready
/foo.cm/ready
/quit/quit

图4 - send_cmds脚本登录并执行foo命令巨集

send_cmds -IPAddress 192.168.77.128 -InputFilePath test.send_cmds -no_Verbose -a
+rg0密码

       PHOENIX CAC VOS测试系统 (%phx_vos#m16)

   *** 要在不同的VOS版本上启动,见***。
   *** >Overseer>COMMON>cfg>reconfig_instructions ***

OpenVOS 17.1.0ax版本,模块%phx_vos#m16。
请登录 08:15:01
登录 nd
密码?
Noah_Davids.CAC于13-04-21 08:15:01 mst.登录%phx_vos#m16。
[f[J[?7l[20l=[1m[1;24r[f[J[J[24;80f
[0;1m准备好了 08: 15: 01
[0mset_terminal_parameters -terminal_type ascii -pause_lines 0。
[1mset_terminal_parameters -terminal_type ascii -pause_lines 0。

准备就绪 08:15:01
foo.cm
display_system_usage
模块 %phx_vos#m16, G94330, OpenVOS 17.1.0ax 的使用统计。
全部762.6小时(31.7天)了。
----CPU----- 最后一分钟 最后5分钟 最后一小时 全部上升时间
.. . . .
国际时间 0.00 0.1% 0.02 0.1% 0.23 0.1% 191.65 0.1
netstat -statistics
tcp:
.. . . 
       201766 tcpOutRsts

analyze_system -request_line stcp_meters -all -long -quit
OpenVOS 17.1.0ax版,analyze_system 17.1.0ax版。
当前进程为884,第8D3E6000步,Noah_Davids.CAC。

stcp_meters %phx_vos#m16 762:36:19 13-04-21 08:15:02
 . . . .
   bufdat执行了678次(平均0.0002/秒)。

准备好了 08:15:02
准备好了 08:15:03

图5 - send_cmds的执行

 

期待。

在gnu_library中,有一个叫做expect的程序。期待脚本的语法可以非常复杂,它允许根据不同的返回字符串进行分支,这样你就可以智能地处理错误,而不是直接超时。你可以在网上查看例子,只要搜索"expect脚本例子"即可。我将介绍一个简单的脚本,只是登录并执行foo.cm宏。请注意,在gnu_tools的早期版本中存在一些bug(这就是为什么我写了send_cmds),但从3.4.0a版本开始,你应该就可以了。虽然我没有展示它,但是 expect 也可以使用参数,所以密码不一定是脚本的一部分,或者脚本可以提示你输入密码。我再次截断了脚本的命令输出,你可以看到,字符定位字符串中的非控制字符被显示出来,直到我将终端类型设置为ascii。不过Expect对字符串的过滤方式不同,所以并不是所有的字符都会显示。

spawn "telnet"        
期待"telnet>"
发送"open 192.168.77.128r"
期待"登录"
发送"登录ndr"
期待"密码"
发送"passwordr"
盼"好"了
发送"set_terminal_parameters -terminal_type ascii -pause_lines 0r"
盼"好"了
发送"foo.cmr"
盼"好"了

图6 - 期待脚本能登录并执行foo命令宏

>bin>expect test.expect
生成远程登录
telnet> 打开 192.168.77.128。
正在尝试...
连接到192.168.77.128。
转义字符是'^]'。


       PHOENIX CAC VOS测试系统 (%phx_vos#m16)

   *** 要在不同的VOS版本上启动,见***。
   *** >Overseer>COMMON>cfg>reconfig_instructions ***

OpenVOS 17.1.0ax版本,模块%phx_vos#m16。
请登录 08:51:28
登录 nd
密码?

Noah_Davids.CAC于13-04-21 08:51:28 mst登录%phx_vos#m16。
fJ?7l20l
0;1m准备好了 08: 51: 28
1mset_terminal_parameters -terminal_type ascii -pause_lines 0。
准备好了 08:51:28
foo.cm
display_system_usage
模块 %phx_vos#m16, G94330, OpenVOS 17.1.0ax 的使用统计。
全部763.2小时(31.8天)了。

----CPU----- 最后一分钟 最后5分钟 最后一小时 全部上机时间
.. . .
国际时间 0.00 0.1% 0.02 0.1% 0.24 0.1% 191.80 0.1
netstat -statistics
tcp:
.. . .
       201926 tcpOutRsts.

analyze_system -request_line stcp_meters -all -long -quit
OpenVOS 17.1.0ax版,analyze_system 17.1.0ax版。
当前进程为895,第8D2E1200步,Noah_Davids.CAC。

stcp_meters %phx_vos#m16 763:12:46 13-04-21 08:51:29。
.. . .
   bufdat执行了678次(平均0.0002/秒)。

准备好了 08:51:29
准备好了 08:51:29

图7 - 期待脚本执行

 

SSH:

最后,你可以使用SSH在远程系统上执行命令。如果你也设置了公钥认证,那么在执行时就不会提示你输入密码。

在使用SSH时,有很多有趣的皱纹。首先缩写不能用,不要试图执行dps,使用display_print_status。

ssh nd@192.168.77.128 dbs   
sh:dbs:找不到命令
准备好了 12: 26: 25

图8 - 使用SSH远程执行命令缩写不成功

ssh nd@192.168.77.128 display_batch_status                    

%phx_vos#m16的批量队列。

QUE STATE 最大的跑步工作机会
正常运行5
准备好了 12: 26: 43

图9 - 使用SSH远程执行命令确实有效

 

第二,直接执行命令宏不成功,注意没有输出,似乎连宏中的第一条命令都只处理了。

ssh nd@192.168.77.128 'foo.cm'        
display_system_usage
准备好了 12: 08: 40

图10 - 使用SSH远程执行命令宏并不总是有效的

 

相反,你必须执行shell命令,并提供命令宏作为其参数。

ssh nd@192.168.77.128 '/bin/sh foo.cm' 。
display_system_usage
模块 %phx_vos#m16, G94330, OpenVOS 17.1.0ax 的使用统计。
全部766.5小时(31.9天)了。

----CPU----- 最后一分钟 最后5分钟 最后一小时 全部上机时间
CPU 分钟 0.02 0.5% 0.09 0.4% 0.91 0.4% 724.76 0.4
.. . .
联网时间时间 0.00 0.1% 0.02 0.1% 0.23 0.1% 192.57 0.1
netstat -statistics
tcp:
.. . .
       202796 tcpOutRsts.

analyze_system -request_line stcp_meters -all -long -quit
OpenVOS 17.1.0ax版,analyze_system 17.1.0ax版。
当前进程为922,第8D3C2780步,Noah_Davids.CAC。

stcp_meters %phx_vos#m16 766:30:14 13-04-21 12:08:57。
.. . .
   bufdat执行了678次(平均0.0002/秒)

准备好了 12: 08: 59

图11 - 使用SSH以shell脚本的方式远程执行命令宏。

 

复杂的宏将无法工作。例如,命令宏的每一行都被分叉为一个单独的进程,所以使用process_dir来保存中间结果的宏将无法工作。请注意,每次调用 analyze_system 都会报告不同的进程号。

ssh nd@192.168.77.128 '/bin/sh foo3.cm' 。   

%phx_vos#m16_mas>SysAdmin>Noah_Davids>foo3.cm 13-04-21 12:52:20 mst

显示foo3.cm
显示屏_行
analyze_system -request_line '' -quit
analyze_system -request_line '' -quit
analyze_system -request_line '' -quit


OpenVOS 17.1.0ax版,analyze_system 17.1.0ax版。
目前的进程是 1028,第8D3C3000步,Noah_Davids.CAC。
OpenVOS 17.1.0ax版,analyze_system 17.1.0ax版。
目前的进程是 1029,第8D3C3000步,Noah_Davids.CAC。
OpenVOS 17.1.0ax版,analyze_system 17.1.0ax版。
目前的进程是 1030,第8D3C3000步,Noah_Davids.CAC。
准备好了 12: 52: 21

图12 - 宏中的每条命令都被分叉为一个独立的进程。

 

使用带有VOS风格变量的命令宏会产生语法错误,因为shell不知道它们是什么。foo3.cm命令宏显示自己,然后数到9。执行显示命令,"&set"会产生语法错误。

ssh nd@192.168.77.128 '/bin/sh foo3.cm'                                       

%phx_vos#m16_mas>SysAdmin>Noah_Davids>foo3.cm  13-04-22 07:33:18 mst

display foo3.cm
&set COUNT 1
&label again
display_line &COUNT&
&set COUNT (calc &COUNT& + 1)
&if &COUNT& < 10 &then &goto again

foo3.cm: line 2: syntax error near unexpected token `&s'
foo3.cm: line 2: `&set COUNT 1'
ready  07:33:18

图13 - 带有VOS风格变量的命令宏将无法工作。

 

但使用shell变量就可以了。当然,这可能需要对现有的宏进行大量的重写。下面是一个同样的宏作为shell脚本的例子。

ssh nd@192.168.77.128 '/bin/sh foo3u' 。   
猫咪
计数=1
while [[ $count -le 9 ]]
做
    echo "$count"
    (( count++ ))
妥当
1
2
3
4
5
6
7
8
9
准备好了 07: 44: 41

图14 - 使用shell stype变量的shell脚本确实有效。

 

然而,你可以把你的VOS风格的命令宏作为一个启动的进程来运行,然后显示产生的输出文件。宏start_foo3.cm运行start_process,等待进程终止,然后显示没有头的输出文件。我对foo3.cm进行了修改,关闭了命令行和宏行,也关闭了准备好的提示符,以便更充分地模仿命令宏交互运行的输出。

start_process foo3.cm -wait     
display foo3.out -no_header

图 15 - 运行 foo3.cm 作为启动进程的命令宏

 

除了前两行的登录头和命令宏名称,以及最后的"Process finished"行之外,结果和在VOS命令行中运行宏是一样的。

ssh nd@192.168.77.128 '/bin/sh start_foo3.cm'                                 
Noah_Davids.CAC logged in on %phx_vos#m16 at 13-04-22 10:45:23 mst.
foo3.cm

%phx_vos#m16_mas>SysAdmin>Noah_Davids>foo3.cm  13-04-22 10:45:23 mst

&echo no_input_lines no_command_lines no_macro_lines
set_ready -format off
display foo3.cm
&set COUNT 1
&label again
display_line &COUNT&
&set COUNT (calc &COUNT& + 1)
&if &COUNT& < 10 &then &goto again

1
2
3
4        
5
6
7
8
9
Process finished.
ready  10:45:25

图16 - 在启动的进程中运行foo.cm的结果

 

所以,正如你所看到的,虽然你不能使用telnet,但有其他方法可以自动登录和执行命令。

© 2020 Stratus Technologies.