shell脚本_免输入密码从服务器拷贝文件

一般用scp命令的时候,或者登陆服务器的时候,总是需要在控制台输入密码!怎么避免呢?


如图,在服务器a上写一个脚本,

1、set ip [lindex $argv 0]   即设置一个变量ip,值为从控制台传入的第一个参数

    expect接收参数的方式和bash脚本的方式不太一样,

        bash是通过$0 ... $n 这种方式,

        而expect是通过set <变量名称> [lindex $argv <param index>]。

        例如set ip [lindex $argv 0]表示把ip作为第一个参数,使用ip的值时用 $ip即可

2、spawn这一行是脚本要执行的操作,如登陆,拷贝文件,上传到其它服务器上等。

3、timeout:

        expect命令中的timeout,spawn命令的时候,如果expect输出match了我们控制台(屏幕)上的内容,我们就会send一个命令上去,模拟用户输入。

        但是expect中等待命令的输出信息是有一个timeout设定,默认是10秒。这个特性是防止那些执行死机的命令的。一旦到了这个timeout,还是没有屏幕输出的话,expect脚本中下面的代码就会执行。。

         解决办法就是在expect脚本的开头定义: 

            set timeout -1 -- 没有timeoutset 

            timeout XX -- 设定具体的timeout时间(XX秒)

4、expect{}里,则是满足控制台的两种情况,第一次登录时,send  yes以及密码。。不是第一次登陆,则直接send密码。

执行:./ copyLog.sh 服务器ip地址

结果:不用手动输入密码,自动执行,文件拷贝成功,如下图:



脚本后续改动了一下:

#!/usr/bin/expect

set ip [lindex $argv 0]
set appid [lindex $argv 1]
set timeout -1
spawn scp -o StrictHostKeyChecking=no -P 22 -r 用户名@$ip:/data/log/app/$appid/access.log /data/test
expect {
"(yes/no)?" {
send "yes\n"
expect "*assword:" { send "密码\n"}
}
"*assword:" {
send "密码\n"
}
}

expect eof

首次 ssh 登陆时提示确认 yes/no,确认 yes 后会把远程节点加入到本地的 ~/.ssh/known_hosts 中,下次再连接同一节点则不再提示。为了省事不确认,可以使用如下参数登陆    ssh -o StrictHostKeyChecking=no  ...这样便不再确认且自动把远程主机的信息添加到 ~/.ssh/known_hosts 中。注:不同账号中可使用相同的 ~/.ssh/known_hosts 文件