C++环境下的expect远程命令执行

来源:互联网 发布:淘宝哪家螺蛳粉好吃 编辑:程序博客网 时间:2024/04/30 12:36

首先,必须安装几个开发包,在centos/fedora下,可以使用yum安装:

  1. $ yum -y install tcl-devel expect-devel  

 

装完以后,就可以使用expect来写代码了,从网上拉下来一段代码,稍微修改了一下:

  1. #include <tcl.h>  
  2. #include <expect.h>  
  3. #include <stdio.h>  
  4. #include <unistd.h>  
  5. #include <iostream>  
  6. #include <expect_tcl.h>  
  7.   
  8. using namespace std;  
  9.   
  10. int main()  
  11. {  
  12.     extern int exp_timeout;  
  13.     exp_timeout = 100;  
  14.     Tcl_Interp *tcl;  
  15.     tcl = Tcl_CreateInterp();  
  16.     if (Expect_Init(tcl) != TCL_OK)  
  17.     {  
  18.         puts("failure");  
  19.         return 1;  
  20.     }  
  21.     //start a connection with remote ssh server  
  22.     int fd = exp_spawnl("ssh""ssh""-p 22""username@server_address""echo start;ls ~;", (char *)0);  
  23.     if(fd < 0)  
  24.     {  
  25.         cout<<"Fail to ssh"<<endl;  
  26.         return -1;  
  27.     }  
  28.     int loop = 1;  
  29.     int result;  
  30.     while(loop)  
  31.     {  
  32.         //predefine some expected responses  
  33.         result = exp_expectl(fd, exp_glob, "*assword: ", 1, exp_exact, "Permission denied, please try again.", 2, exp_regexp, "(The authenticity of host)(.)*(Are you sure you want to continue connecting (yes/no)?)", 3, exp_end);  
  34.         char pas[] = "your_password\n";  
  35.         switch(result)  
  36.         {  
  37.             case 1:  
  38.                 write(fd, pas, sizeof(pas) - 1);  
  39.                 break;  
  40.             case 2:  
  41.                 cout <<"wrong password"<<endl;  
  42.                 break;  
  43.             case 3:  
  44.                 cout<<"connect security"<<endl;  
  45.                 write(fd, "yes\n", 4);  
  46.                 break;  
  47.             case EXP_EOF:  
  48.                 cout << "EOF\n";  
  49.                 loop = 0;  
  50.                 break;  
  51.             case EXP_TIMEOUT:  
  52.                 cout<<"Time out\n";  
  53.                 loop = 0;  
  54.                 break;  
  55.             default:  
  56.                 cout<<"logged in "<<result<<endl;  
  57.                 loop = 0;  
  58.                 break;  
  59.         }  
  60.     }  
  61.     Tcl_DeleteInterp(tcl);  
  62. }  

 

 

保存为test-expect.cpp, 编译:

  1. g++ test-expect.cpp -o test-expect -lexpect5.43 -ltcl8.4  

 

执行./test-expect,得到远程root用户的根目录列表。 

远程命令的标准输出存在exp_buffer缓冲区。

 

详细的手册可以参考http://www.cims.nyu.edu/cgi-systems/man.cgi?section=3&topic=libexpect