免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 8163 | 回复: 6

调用 passwd 命令自动修改密码,非 Expect [复制链接]

论坛徽章:
0
发表于 2011-03-04 21:17 |显示全部楼层
  1. #!/usr/bin/env perl

  2. use strict;
  3. use warnings;
  4. use IO::Pty;
  5. use IO::Select;
  6. # use Term::ReadKey;

  7. usage() if ($#ARGV < 1);

  8. my $pty = IO::Pty->new();
  9. my $select = IO::Select->new($pty);
  10. my $buffer = "";

  11. my $pid = fork();
  12. die "Fork fail!\n" if (not defined $pid);
  13. if ($pid != 0) {
  14.     my $loop = 1;
  15.     local $SIG{CHLD} = sub { $loop = 0; };
  16.     while ($loop) {
  17.         expect();
  18.     }

  19.     expect();
  20.     waitpid($pid, 0);
  21. }
  22. else {
  23.     my $slave = $pty->slave();
  24.     open(STDIN, "<&", $slave);
  25.     open(STDOUT, ">&", $slave);
  26.     open(STDERR, ">&", $slave);
  27.     close $pty;
  28.     close $slave;
  29.     exec("passwd");
  30.     exit 1;
  31. }

  32. ################################

  33. sub usage {
  34.     print STDERR "$0 Password NewPassword\n";
  35.     exit 0;
  36. }

  37. sub expect {
  38.     my ($r, $w, $e) = IO::Select->select($select, $select, undef, 0.02);
  39.     if ($#$r > -1) {
  40.         if (sysread($pty, my $buf, 8196)) {
  41.             $buffer .= $buf;
  42.             syswrite(STDOUT, $buf);
  43.         }
  44.     }
  45.     else {
  46.         return;
  47.     }
  48.    
  49.     if ($#$w > -1) {
  50.         if ($buffer =~ /\(current\) UNIX password:/) {
  51.             $buffer = "";
  52.             syswrite($pty, "$ARGV[0]\r");
  53.         }
  54.         elsif ($buffer =~ /New UNIX password:/) {
  55.             $buffer = "";
  56.             syswrite($pty, "$ARGV[1]\r");
  57.         }
  58.         elsif ($buffer =~ /Retype new UNIX password:/) {
  59.             $buffer = "";
  60.             syswrite($pty, "$ARGV[1]\r");
  61.         }
  62.         else {
  63.             ;
  64.         }
  65.     }
  66. }
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2011-03-05 08:37 |显示全部楼层
这个其实就是 Expect 的简易版,
以及 screen 实用工具的主要工作原理。

支持一下,加个精华。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2011-03-05 08:42 |显示全部楼层
发布代码时,
如果能够对代码的主要意图加以说明,并且指出一些注意事项,就更加完美了。
就像下面这样:

http://bbs.chinaunix.net/redirec ... 203&pid=8215506
如同标题所说,本程序旨在演示如何操纵伪终端和交互式应用程序通信,
因此对于 passwd 实用工具的输出解析并不多,只是做了一些简单的判断。

事实上,根据输入内容的不同,passwd 实用工具的输出信息多达十多种,PAM 的到来使得 passwd 的输出更加复杂,
因此如果希望能够自动控制 passwd,那么还是用 expect/perl 等工具较为方便。

另外需要说明的一点是,自动控制交互式应用程序运行时,尽量运行其英文版本,这样信息会规范一些从而有利于捕获并匹配。
中文或者其它语种的信息不仅要考虑到编码的问题,而且信息用语经常会有变化。

通过设定环境变量 LANG=C,可以使 passwd 实用工具的输出变成英文。
flw 发表于 2008-04-14 19:03

论坛徽章:
0
发表于 2011-03-06 08:58 |显示全部楼层
发布代码时,
如果能够对代码的主要意图加以说明,并且指出一些注意事项,就更加完美了。
就像下面这样: ...
flw 发表于 2011-03-05 08:42



  flw 说得是

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
发表于 2011-03-07 11:02 |显示全部楼层
flw 说得是
黑色阳光_cu 发表于 2011-03-06 08:58



    请问一下,expect()是什么子例程?是perl内建的还是从哪个模块导入的?

论坛徽章:
0
发表于 2011-08-12 23:49 |显示全部楼层

学习!

论坛徽章:
0
发表于 2011-10-14 10:42 |显示全部楼层
支持一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP