Chinaunix首页 | 论坛 | 博客
  • 博客访问: 207953
  • 博文数量: 39
  • 博客积分: 1057
  • 博客等级: 准尉
  • 技术积分: 926
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-27 20:13
文章分类

全部博文(39)

文章存档

2012年(24)

2011年(15)

分类: Python/Ruby

2011-07-16 12:34:34

   学习模块的最快方法就是学习实例,下面介绍Perl的Net::OpenSSH模块的使用实例,详细的说明可以参考CPAN上的介绍。

本机通过key登陆远程服务器,所以要先安装openssh,关于使用ssh公私密钥可以参考man手册。

1、连接一台远程服务器并执行命令或者脚本

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Net::OpenSSH;

  4. my $hostname = 'puppet.ygfs.com';
  5. my $ssh = Net::OpenSSH->new( $hostname, user => 'root' );

  6. my $cmd = 'ls -l /';
  7. my $svn_cmd = 'bash /data/ygfs_ctrl/db_convert.sh';     #这里是在远程执行一个bash shell脚本

  8. open LOG,">> perl_exec.log";                            #记录执行日志
  9. select LOG;

  10. my @out = $ssh->capture( $cmd );
  11. print "@out";

  12. my @db_out = $ssh->capture( $svn_cmd );
  13. print "@db_out";

  14. close LOG;
  15. select STDIN;
2、连接多台远程服务器,并执行命令或者脚本

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Net::OpenSSH;

  4. my @hostname = qw(                              #建立一个服务器列表
  5.                 puppet1.ygfs.com
  6.                 puppet2.ygfs.com
  7.                 );

  8. my $cmd1 = 'ls -l';
  9. my $cmd2 = 'df -i';


  10. for my $host ( @hostname ) {

  11.         my $ssh = Net::OpenSSH -> new( $host, timeout => 600 );
  12.         my @out = $ssh -> capture( $cmd1 );
  13.         my @space = $ssh -> capture( $cmd2 );
  14.         print @out;
  15.         print @space;

  16. }

  17. print "@hostname\n";
3、从参数列表读取要连接的远程服务器和要执行的命令

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Net::OpenSSH;

  4. my $hostname   = $ARGV[0] || 'puppet.ygfs.com';
  5. my $remote_cmd = $ARGV[1] || 'hostname && uname -p';


  6. my $ssh = Net::OpenSSH -> new( $hostname );
  7. my @exec_log = $ssh -> capture( $remote_cmd );
  8. print @exec_log;
 
4、使用管道

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Net::OpenSSH;

  4. my $hostname = $ARGV[0] || '127.0.0.1';

  5. my $ssh = Net::OpenSSH -> new( $hostname );

  6. my @lists = $ssh -> capture( 'ls' );
  7. print @lists;

  8. my @lists_format = $ssh -> capture2( 'ls -hl' );
  9. print @lists_format;


  10. #通过pipe_out方法获取远程主机上指定文件的内容,保存到$rout句柄,并打印输出,这里可以不使用pid变量

  11. my ( $rout,$pid ) = $ssh -> pipe_out( "cat install.log" )
  12. #my $rout = $ssh -> pipe_out( "cat install.log" )
  13.         or die "pipe_out method failed:".$ssh -> error;

  14. while( <$rout> ) { print }
  15. close $rout;

  16. #写内容到远程服务器的指定文件
  17. my $rin = $ssh -> pipe_in( "cat >> nginx.conf" )
  18.         or die "pipe_in method failed:".$ssh -> error;

  19. print $rin <<EOF;
  20. server{
  21.         listen 8088;
  22.         root /data/private_web;
  23.         index index.html;
  24.         server_name private.yuanfang.com;
  25.         auto_index on;
  26.         access_log /dev/null;
  27.         error_log /dev/null;
  28.       }
  29. EOF
  30. close $rin;

   这里只是简单的介绍了Net::OpenSSH模块怎么使用,它还有很多方法和参数,读者可以参考手册。
   从上面的例子可以看到,这个模块不是并发连接到远程主机和执行命令的,所以对于要连接的对象很多的时候,耗时很长,效率很低,所以就有了Net::OpenSSH::Parallel模块,支持指定工作进程数和并发数量。下篇博文将会介绍。

阅读(3293) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

jack10072013-01-13 20:17:14

发送echo '$$$$$$'命令的时候,$$会先被perl解释,然后把解释后的命令,发送到远程机器执行,怎么禁止perl解释要发送的命令。

邝文琳2012-11-01 20:18:00

请问使用OpenSSH怎样可以绕过首次访问时候的:
Are you sure you want to continue connecting (yes/no)? yes
这个自动输入yes,不想使用expect