expect的确是UNIX中一个很有用的
工具,可以完成很多匪夷所思的任务。官方网址:http://expect.nist.gov/
基本不用什么参考书,网上提供的expect包中有很多
例子,加上man文档,基本就会了。至于TCL/TK之类的,也不难学,其实只要稍稍了解一下就可以用expect了。不想用TCL的也可以用
perl, 或python里面的expect库。
1>
自动化自动登录
#!/bin/sh -f
#\
exec expect $0 $@
spawn ssh localhost
expect "password"
send "your passwd\r"
interact
2> 使用libexpect实现interact
以下适用于
linux.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/select.h>
#include <expect.h>
int main (int argc, char *argv[])
{
int fd, ret, i;
fd_set rset;
struct termios new, old;
char buf[1024];
if (argc < 2)
{
printf ("Usage: %s <command> [<args>...]\n", argv[0]);
exit (1);
}
fd = exp_spawnv (argv[1], &(argv[1]));
if (fd < 0)
{
perror ("exp_spawnv()");
exit (-1);
}
/* set the FD and stdin to non-blocking mode */
/* if (fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK))
{
perror ("fcntl()");
exit (-1);
}
if (fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK))
{
perror ("fcntl(0)");
exit (-1);
}
*/
/* put the stdin tty into raw mode */
if (tcgetattr (0, &old))
{
perror ("tcgetattr()");
exit (-1);
}
memcpy (&new, &old, sizeof (struct termios));
cfmakeraw (&new);
if (tcsetattr (0, TCSANOW, &new))
{
perror ("tcsetattr()");
exit (-1);
}
for (ret = 0;;)
{
FD_ZERO (&rset);
FD_SET (0, &rset);
FD_SET (fd, &rset);
if (select (fd + 1, &rset, NULL, NULL, NULL) < 0)
{
perror ("select()");
ret = -1;
break;
}
if (FD_ISSET (0, &rset))
{
i = read (0, buf, sizeof (buf));
if (i < 0)
{
if ((errno != EINTR) && (errno != EAGAIN))
{
perror ("read(0)");
ret = -1;
break;
}
}
else if (i > 0)
{
if (write (fd, buf, i) != i)
{
perror ("write()");
ret = -1;
break;
}
}
else
{
break; /* EOF on stdin */
}
}
if (FD_ISSET (fd, &rset))
{
i = read (fd, buf, sizeof (buf));
if (i <= 0)
{
if ((errno != EINTR) && (errno != EAGAIN))
{
/* just call it EOF; we seem to get EIO on EOF */
break;
}
}
else if (i > 0)
{
if (write (1, buf, i) != i)
{
perror ("write(1)");
ret = -1;
break;
}
}
}
}
if (tcsetattr (0, TCSANOW, &old))
{
perror ("tcsetattr()");
ret = -1;
}
close (fd);
exit (ret);
}