请教自动登陆ssh,然后ftp自动传文件的脚本

请教自动登陆ssh,然后ftp自动传文件的脚本

perl可以实现?
可以..但是你也可以考慮用expect  去寫...
因為perl要做到也一樣是用Expect.pm

#!/usr/local/bin/expect --

eval spawn /usr/local/bin/ssh -l apile 10.1.1.1
expect {
   timeout   { puts "no answer from $HI_HOST" ; exit 0}
   "assword:" {send $HI_PASSWD\r }
   "yes/no)? " {send "yes\r" }
   "Unknown" { puts "unknown host\r" ; exit 0}
   }
expect {
   timeout   { puts "no answer from $HI_HOST" ; exit 0}
   "invalid login name or password"   { puts "login fail\r" ; exit 0 }
   "Login incorrect"   { puts "login fail\r" ; exit 0 }
   "ermission denied"   { puts "login fail\r" ; exit 0 }
   "$ "  { puts "$HI_HOST login ok\r" ; log_file [lindex $argv 1] ; send "ping -w 15 -c [lindex $argv 2]  [lindex $argv 0]\r" }
   "$ "  { puts "$HI_HOST login ok\r" ; log_file [lindex $argv 1] ; send "ping -w 15 -c [lindex $argv 2]  [lindex $argv 0]\r" }
   }
set timeout 15

if { "[lindex $argv 2]"=="2" } then { set timeout 15 }

expect {
   timeout   { puts "Can't ping to [lindex $argv 0]" ; send "\003" }
   "100% packet loss"  { puts "ing err \r" }
   " 0% packet loss"   { puts "ing OK \r" ; log_file ; exit 1 }
   ">; "      { puts "ing ok\r" ; log_file ; exit 1 }
   "$ "      { puts "ing ok\r" ; log_file ; exit 1 }
   }
log_file
exit 1

你可以man expect去看看怎麼實作...
上面這個例子是我先用ssh連到某台主機上去輸入ping的指令...
谢谢。
我还是想用Expect.pm,用CPAN 安装Expect.pm感觉上比直接装Expect简单。
对我来讲越简单越好。

用Expect.pm,有没有例子,让我参考参考。(照猫画虎)   
下面是我用來做兩次telnet的程序...你可以參考並修改..
要不可以去www.cpan.org去找Expect.pm的說明文件..

use Expect;
$NM_ID = "aaa";
$NM_PWD = "aaabbb";
$NE_ID = "ccc";
$NE_PWD = "dddeee";
$timeout = 30;

$exp = new Expect;

## 設定terminal type
#$exp->;stty(qw(-raw -echo));
## 重設定buffer 大小
#$exp->;match_max(1024);
## 重設定timeout時間(有收到東西就重設定)
$exp->;restart_timeout_upon_receive(1);
## 看詳細內容
#$exp->;exp_internal(1);
## 開啟Debug模式
#$exp->;debug(2);
#$exp->;send_slow(0);
## 顯示標準輸出
$exp->;log_stdout(0);

$exp->;spawn("telnet $NM_IP" || die "cannot spawn telnet: $!\n";
$error_value =0;
$spawn_ok =0;
$exp->;expect( $timeout,
             [ qr'login: $',
               sub {
                 $spawn_ok = 1;
                 my $fh = shift;
                 $fh->;send("$NM_ID\r";
                 $fh->;clear_accum();
                 exp_continue; } ],
             [  qr'sword: $' ,
               sub {
                 $spawn_ok = 2;
                 my $fh = shift;
                 $fh->;send("$NM_PWD\r";
                 $fh->;clear_accum();
                 exp_continue; } ],
             [ qr'Login incorrect',\&nm_error],
             [  eof =>; \&nm_error ],
              [  timeout =>; \&nm_error ],
             '-re', qr'\012\$ $',
               sub {
                 my $fh = shift;
                 $fh->;send("telnet $DSLAM_IP\r";
               }
            );
$spawn_ok = 0;
$exp->;expect( $timeout,
           [ qr'Invalid name.',\&ne_error],
           [ qr'Invalid password.',\&ne_error],
           [ qr'Login:\s+$',
             sub {
               $spawn_ok = 1;
               my $fh = shift;
               $fh->;send("$NE_ID\r";
               $fh->;clear_accum();
               exp_continue; } ],
           [  qr'sword: $' ,
             sub {
               $spawn_ok = 2;
               my $fh = shift;
               $fh->;send("$NE_PWD\r";
               $fh->;clear_accum();
               exp_continue; } ],
           [  eof =>;\&ne_error ],
           [  timeout =>; \&ne_error ],
             '-re', qr'\d+>; $',
               sub {
                 my $fh = shift;
                 $fh->;send("login\r";
               }
           );

$exp->;expect( $timeout,
           [  eof =>;\&run_error ],
           [  timeout =>; \&run_error ],
             '-re', qr'>; $',
           );
}
===>;任何我想expect要我做的事情



sub run_error{
  $exp->;log_file($LOG_FILE);
  $exp->;log_file->;print("\r\n無法下指令##\r\n";
  $error_value = 999;
}

sub nm_error {
  $exp->;log_file($LOG_FILE);
  if($spawn_ok == 1) {
    $exp->;log_file->;print("\r\n帳號密碼錯誤\r\n";

  }elsif($spawn_ok == 2) {
    $exp->;log_file->;print("\r\n無法登錄\r\n";

  }else{
     $exp->;log_file->;print("\r\n#10# 無法連線\r\n");
  }
  $error_value = 10;
  $exp->;log_file(undef);
#  $exp->;hard_close;
  die "10\n";
}
sub ne_error {
  $exp->;log_file($LOG_FILE);
  if($spawn_ok == 1) {
    $exp->;log_file->;print("\r\n登錄失敗\r\n");

  }elsif($spawn_ok == 2) {
    $exp->;log_file->;print("\r\n無法登錄\r\n");

  }else{
    $exp->;log_file->;print("\r\n#12# 無法連線\r\n");

  }
  $error_value = 12;
  $exp->;log_file(undef);
#  $exp->;hard_close;
  die "12\n";
}


[Copy to clipboard] [ - ]
CODE:
#!/usr/local/bin/perl

use Expect;

my $timeout = 2;
my $delay = 1;
my $cmd         = "ssh";
my @params = qw/202.108.xx.xx -luser -p22/;
my $pass = "password";

$exp = Expect->;spawn($cmd, @params) or die "Can't spawn $cmd\n";

$exp->;expect($timeout, -re=>;'[Pp]assword:');
$exp->;send_slow($delay, "$pass\r\n");

$exp->;interact();
$exp->;hard_close();

exit 0;

这个脚本我每天都用,你修改一下@params,就没问题了,
因为我用的命令行是ssh 202.108.xx.xx -luser -p22
所以我不用spawn "login"或者是"user"等字样。

如果你需要抓login等字样,就在send passwd前面加上:

[Copy to clipboard] [ - ]
CODE:
my $user = "username";
$exp->;expect($timeout, 'login:');
$exp->;send_slow($delay, "$user\n");

ftp本身提供auto login功能,所以你可以直接使用ftp -i -in <xxx.ftp来进行自动操作。
而且也可以借助Net::Ftp模块。无须使用Expect了。 :)
谢谢个位。
    

>;借助Net::Ftp模块。无须使用Expect了
这个好像比较简单,能否举个小例子。有个大概模样就行。


不好意思。
我的方法比較複雜是因為我要用這個功能與四五百部設備做溝通..
這些設備分別給數部unix server管理..因為每台unix的id/passwd都不一樣..
只好寫得很複雜..幫助了解是什麼原因造成無法連線..
deachcult說用Net::Ftp是指你要從你用ssh連過去的機子上面..利用
crontab 執行shellscript..
ftp_data.sh
====================
#!/bin/ksh
PATH=/usr/sbin:/usr/local/bin:/opt/sfw/bin:/opt/schily/bin::/usr/dt/bin:/usr/openwin/bin:.:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/opt/hpnp:/usr/etc:/usr/ucb:/etc:/usr/ccs/bin:/opt/SUNWspro/bin:/opt/SUNWste/bin:/etc/opt/licenses:/usr/local/samba/bin:/:/usr/local/samba/bin
export PATH
export TERM=vt100
LC_CTYPE=iso_8859_1
export LC_CTYPE
cd /localdir/
ftp -n 10.1.1.1 <<END
user username password
binary
prompt
cd /remotedir
mput *
quit
END
>;deachcult說用Net::Ftp是指你要從你用ssh連過去的機子上面..利用
>;crontab 執行shellscript..

白把我乐够呛。
心里还琢磨Net::Ftp怎麽功能这麽强大。竟然不知道。