我们常用sudo,ssh、ftp命令操作服务器或者修改权限的时候都会要求输入password,但是shell脚本运行中该如何交互实现自动输入密码呢?

下面总结三种实现方法。

一、重定向:
用重定向方法实现交互的前提是指令需要有参数来指定密码输入方式,如ftp就有-i参数来指定使用标准输入来输入密码
shell用重定向作为标准输入的用法是:

ftp -i -n 192.168.15.16<<EOF
user john pw@2018
ls
EOF
二:管道:
跟重定向一样,指令同样要有参数来指定密码输入方式,如sudo的-S参数,passwd的-stdin参数,所以实现sudo自动输入密码的脚本如下:其中pw@2018为密码

echo 'pw@2018' | sudo -S cp fileone /tmp
实现自动修改密码的脚本写法如下:

echo 'password' | passwd -stdin username
三:expect:
上面介绍的两种方法前提条件是指令有参数来设定密码输入方式,像ssh指令就没有这样的参数,第三种交互方式就派上用场了,expect就是用来做交互用的,基本任何交互登录的场合都能使用,但是需要安装expect包。
CentOS下安装命令很简单:

sudo yum install expect
Mac用户,可以通过homebrew安装(需要先安装homebrew)

brew install expect
测试脚本:实现rsync定时同步远程服务器文件
我们写一个简单的脚本,在脚本里配置密码,保存为scp.exp如下:

1,先写好rsync.ex脚本文件,在脚本里定义变量和保存密码

!/usr/bin/expect

set timeout 20

if { [llength $argv] < 2} {

puts "Usage:" 
puts "$argv0 remote_path local_file" 
exit 1 

}

set remote_path [lindex $argv 0]
set local_file [lindex $argv 1]
set passwd yourpassword

set passwderror 0

spawn rsync -avz --delete --exclude 'var' $remote_path $local_file

expect {

"*assword:*" { 
    if { $passwderror == 1 } { 
    puts "passwd is error" 
    exit 2 
    } 
    set timeout 1000 
    set passwderror 1 
    send "$passwd\r" 
    exp_continue 
} 
"*es/no)?*" { 
    send "yes\r" 
    exp_continue 
} 
timeout { 
    puts "connect is timeout" 
    exit 3 
} 

}
脚本说明:

如果是sh脚本,第一行是#!/bin/bash,而这里是你机器上expect程序的路径,说明这段脚本是由expect来解释执行的
第一句是设定超时时间为20s
set passwd yourpassword设置成你自己的密码
spawn是expect的语句,执行命令前都要加这句

2,把rsync.ex写到定时任务里

crontab -e
编辑如下,根据你自己的具体情况设置crontab参数和rsync.ex文件路径:

相关文章:CentOS等Linux服务器配置使用Rsync同步及Crontab定时任务

单独运行rsync.ex文件,如下:

expect /home/backup/rsync.ex [email protected]:/home/backup/* /local/backup/
注意:expect跟bash类似,使用时要先登录到expect,所以首行要指定使用expect
在运行脚本时候要expect rsync.ex,不能sh rsync.ex了

文章目录