问题描述

前几天有个小需求,用到expect脚本去循环的发送一些数据,主要问题代码如下:

 #! /usr/bin/expect
while {true} {
set timeout 60
spawn telnet ip port
expect "]'.";
send "***********一些数据***********\r"
expect "*********一些回复************";
send "exit\r"
expect "Connection closeed by foreign host.";
expect eof
sleep 10
}

单单看到这段代码,并没有发现什么问题,但是运行几个小时之后,收到一个错误:

 buffer overflow detected *** : /usr/bin/expect terminated
========Backtrace: ========
... ...

内存越界?开始排查原因,虽然走了一些弯路,不过终于还是找到了答案:

首先,我们查看该进程的pid,然后进一步通过pid去进程fd文件夹下看看

[root]# ps -ef|grep expect.sh
root 17761 30111 .....
[root]# cd /proc/17761/fd/
[root]# ls -a
...

可以看到该进程已经产生了非常多的子进程句柄,赶紧ps -ef|grep 17761看一下:

[root]# ps -ef|grep 17761
root 23424 17761 ... [telnet] <defunct>
root 23426 17761 ... [telnet] <defunct>
root 23431 17761 ... [telnet] <defunct>
root 23434 17761 ... [telnet] <defunct>
root 23438 17761 ... [telnet] <defunct>
root 23439 17761 ... [telnet] <defunct>
root 23455 17761 ... [telnet] <defunct>
...

原来这个脚本产生了大量的telnet僵尸进程,导致句柄都用完了,但看上面的脚本,每次telnet都退出了,也都expect eof结束了进程,怎么会变成僵尸进程呢?

原因分析

很多人expect脚本用的不多,基本都是参照网上的例子来完成自己的需求,然后网上的博客大多都是转载来转载去,这导致有些细节问题不常被提及。

首先spawn会开启一个子进程(spawn_id)去执行命令,expect eof用于等待进程结束,另外有一个close命令用于直接结束子进程(根据spawn_id来定位子进程)。问题在于eof 和 close都只是杀死子进程,但子进程变为僵尸进程依然存在进程列表中,僵尸进程会占用句柄,但是句柄是有限的,大量僵死进程的产生,导致整个脚本进程无法继续运行,报错退出。

网上的例子大多是流程式的脚本,不是本文这种循环运行的,所以等待eof后,主进程退出,将僵尸进程也回收了,因此不会有任何问题。

不退出主进程,还要及时回收僵尸子进程,很多语言都内置了相关的方法,expect脚本也不例外,wait就是负责给子进程收尸的。所以文章开头的脚本应该加上wait来及时回收telnet僵尸进程。

 #! /usr/bin/expect
while {true} {
set timeout 60
spawn telnet ip port
expect "]'.";
send "***********一些数据***********\r"
expect "*********一些回复************";
send "exit\r"
expect "Connection closeed by foreign host.";
expect eof <---------此句可以换成 close,因为上面已经主动关闭了telnet
wait <----------------wait不可缺少
sleep 10
}

最后

代码不在乎简单复杂,很多东西虽然可以省略,但能做到步步为营也不失是一种优秀的品质。

容易忽略的expect脚本问题,暗藏的僵尸进程,wait命令不要漏掉的更多相关文章

  1. 分发系统介绍、expect脚本远程登录、expect脚本远程执行命令、expect脚本传递参数

    7月19日任务 20.27 分发系统介绍20.28 expect脚本远程登录20.29 expect脚本远程执行命令20.30 expect脚本传递参数 20.27 分发系统介绍 公司业务逐渐扩大时, ...

  2. shell脚本嵌套expect脚本

    #!/bin/sh echo "helo" password='xxxx' ###不能在下面的expect脚本段设置成 set password xxxx否则获取不到变量,单独的e ...

  3. 使用expect脚本语言写一键发布服务(代码发布、所有服务重启)

    互联网服务有很多台服务,但是在上线的时候需要将这些服务版本都更新与个个都重启,下面的脚本语言,就是一键发布服务~ 1.在/home/weihu/deploy/ 目录下建下publish .publis ...

  4. Linux 下 expect 脚本语言中交互处理常用命令

    Linux 下 expect 脚本语言中交互处理常用命令 1. #!/usr/bin/expect 告诉操作系统脚本里的代码使用那一个 shell 来执行.这里的 expect 其实和 Linux 下 ...

  5. Mac 让 iTerm2 记住用户名密码 expect 脚本

    刚刚用iTerm2的时候,总是要一遍遍的敲用户名.密码. 我在想, 能不能像Windows的软件一样,可以直接让软件记住.然后只要点击一下,就直接ssh到远程服务器上面去了. 之后经过搜索,可以用ex ...

  6. expect脚本同步文件 expect脚本指定host和要同步的文件 构建文件分发系统 批量远程执行命令

    自动同步文件 #!/usr/bin/expect set " spawn rsync -av root@.txt /tmp/ expect { "yes/no" { se ...

  7. 分发系统介绍 expect脚本远程登录 expect脚本远程执行命令 expect脚本传递参数

    expect脚本远程登录 yum install -y expect yum install -y tcl tclx tcl-devel 自动远程登录 #! /usr/bin/expect set h ...

  8. 与服务器同步工程(expect脚本)

    先看下我实际用的例子: #!/usr/bin/expect spawn rsync -vazu ssh-src/src wayne@192.168.5.2:~/projects/ expect &qu ...

  9. shell脚本通过expect脚本实现自动输入密码(使用expect)

    背景:在远程文件下载时,需要输入对方的服务器密码,shell不支持交互输入内容,可以用下面两种方式实现   一.在shell脚本中嵌入expect来实现密码输入 expect是一个自动交互功能的工具. ...

随机推荐

  1. 【SPOJ】MGLAR10 - Growing Strings

    Gene and Gina have a particular kind of farm. Instead of growing animals and vegetables, as it is us ...

  2. 1083 Cantor表

    题目描述 Description 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 2/ ...

  3. JavaScript中各存在性函数

    JavaScript中有很多表示存在性和从属关系的函数,本文介绍如下几个: 1)有关实例与构造函数原型之间的关系:isPrototypeOf(),Object.getPrototypeOf(); 2) ...

  4. PHP之SimpleXML函数

    使用php创建XML文件十分简单,使用SimpleXML那就更简便了,同时读取XML文件也十分方便.XML文件是直接在浏览器中打开,以自定义标签的方式直观简洁的方式展示给读者. 1.创建XML文件 h ...

  5. 【javascript】javasrcipt设计模式之状态模式

    使用场景 解决多个[ifelse]嵌套,将其封装成若干个方法 区分事物内部的状态,事物内部的状态的改变往往会带来事物的行为的改变 简单的多个状态直接切换的时候 //两个状态之间的切换,使用if-els ...

  6. LintCode2016年8月22日算法比赛----平面列表

    平面列表 题目描述 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 注意事项 如果给定的列表中的要素本身也是一个列表,那么它也可以包含列表. 样例 给定 ...

  7. pmp心得

    我报名比较晚,等缴费最后期限,才缴费,下定决心,开始正式的备考. 我的工作比较忙,备考时间特比较短,从拿到书到考试只有二个月了,心理慌慌的,期间还有一门其他的考试,在5月底,实际时间只能有20来天. ...

  8. 第三课 java编程入门

    java特点: 1.面对象性 2.可移植性/跨平台性 java组成: jdk(java工具开发工具包) /       \              \ jre       指令集合   api和常用 ...

  9. JAXB实现java对象与xml之间转换

    JAXB简介: 1.JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标 ...

  10. ASP.NET Core 2.1以上 Bootstrap 4前端模板文件,开发环境与发布环境前端模板 environment的使用

    笔者的前端文件如下 笔者增加Bootstrap 4 和 FontAwersome(字体图标),因为Bootsrap 4已经不再包含图标了. ASp.Net Core 中,通常在 _Layout.csh ...