linux密码中空格怎么输入,Linux shell 脚本通过expect实现自动输入密码-Fun言

一、expect 简介

expect 是一个自动交互功能的工具,可以实现自动登录,不必手动输入密码(Password)、确认(Yes)等交互操作。

expect 是开了一个子进程,通过spawn来执行shell脚本,except监测到脚本的返回结果,并发送交互输入内容(send)

二、except 安装

1. Ubuntu 安装

sudo apt-get -y install tcl expect

2. CentOS 安装

yum -y install expect

3. MacOS 安装

brew install expect

安装完成后的目录为

# which expect

/usr/bin/expect

三、except 使用

1. expect 使用示例

#!/usr/bin/expect

#

# mimvp.com

# 2016.10.12

set timeout 30

set passwd "mimvp.com"

spawn ssh -l mimvp 123.57.78.100

expect "password:"

send "$passwd\n"

interact

说明:

#!/usr/bin/expect  表示使用expect的shell交互模式,由expect来解释执行的而不是由bash,所以代码的语法和shell脚本也是不一样的

set timeout 30  表示对变量timeout赋值,为30秒。如果执行的shell命令耗时长可以设置超时时间长一些,默认timeout为10秒

set passwd "mimvp.com"  表示对变量passwd赋值,密码供后面的引用。特殊字符需要转义,例如 "\$mimvp.com"

spawn ssh -l mimvp 123.57.78.100  表示在expect下执行shell脚本,例如本例的 ssh 远程登录服务器

expect "password:"  表示对执行shell脚本的返回字符串进行判断,是否包含"password:"字段,一般可写做 "*assword:"

send "$passwd\n"  表示如果expect监测到了包含的字符串,将输入send中的内容,\n相当于回车,有的也写做\r

interact  表示留在新开的子进程内,可以继续输入,否则将退出子进程回到shell中。例如 ssh登录到某台服务器上,只有加了interact才可以留在登录后的机器上进行操作

2. expect 命令行参数

[lindex $argv n]获得参数下标为 index = n 的参数(index从0开始计算)

$argc为命令行参数的个数

[lrange $argv 0 0]表示第一个参数

[lrange $argv 0 3]表示第1到第3个参数

用法示例:

#!/usr/bin/expect

#

# mimvp.com

# 2016.10.12

set timeout 30

set passwd "mimvp.com"

set ipaddr [lrange $argv 0 0]

#set ipaddr [lindex $argv 0]

spawn ssh -l root $ipaddr

expect "password:"

send "$passwd\n"

interact

## ./conn_server.sh 123.57.78.100

上例里,执行语句为

./conn_server.sh 123.57.78.100

其中:

./conn_server.sh  是脚本文件名

123.57.78.100  是服务器IP地址,set ipaddr [lrange $argv 0 0] 获取第一个参数IP地址,并赋值给 ipaddr

spawn ssh -l root $ipaddr  表示使用IP地址,进行ssh登录

例如:scp_service.sh文件,可以 ./scp_service.sh -rm来执行,这时 -rm 是赋值的第一个参数

set option  [lindex $argv 0](获得第一个参数-rm 存到变量option中,参数是的index是从0开始计算的)

3. expect 判断语句

expect支持if语句 if...elif...else...

if { 条件1 } {

条件1执行语句

} elif { 条件2 } {

条件2执行语句

} else {

其他情况执行语句

}

用法示例:

#!/usr/bin/expect

#

# mimvp.com

# 2016.10.12

set timeout 30

set passwd "mimvp.com"

if { [llength $argv] < 2 } {

puts "Usage:"

puts "$argv0 username ipaddr"

exit 1

}

#set username [lindex $argv 0]

#set ipaddr [lindex $argv 1]

set username [lrange $argv 0 0]

set ipaddr [lrange $argv 1 1]

spawn ssh -l $username $ipaddr

expect "password:"

send "$passwd\n"

interact

$ ./conn_server.sh mimvp## error

Usage:

./conn_server.sh username ipaddr

$ ./conn_server.sh mimvp 123.57.78.100## success

说明:

1. if 的条件用{}来包含条件

2. if 和 后面的{}必须有空格隔开

3. 两个花括号之间必须有空格隔开,比如if {} {},否则会报错 expect:extra characters after close-brace

3. 使用{来衔接下一行,所以if的条件后需要加左花括号{

4. else不能单独放一行,所以else要跟在}后面

except 实现 scp 拷贝

#!/usr/bin/expect

#

# mimvp.com

# 2016.10.12

set timeout 30

set passwd "mimvp.com"

if { [llength $argv] < 2 } {

puts "Usage:"

puts "$argv0 local_file remote_path"

exit 1

}

set local_file [lindex $argv 0]

set remote_file [lindex $argv 1]

set passwd_error 0

spawn scp $local_file $remote_file

expect {

"*assword:*" {

if { $passwd_error == 1 } {

puts "passwd is error"

exit 2

}

set timeout 100

set passwd_error 1

send "$passwd\n"

exp_continue

}

"*es/no)?*" {

send "yes\n"

exp_continue

}

timeout {

puts "connect is timeout"

exit 3

}

}

4. expect {} 多行期望

有时执行shell后预期结果是不固定的,有可能是询问是yes/no,有可能是去输入密码,所以可以用expect{}(比如sudo命令,第一次使用sudo时需要输入密码,但是它有5分钟的有效时间,5分钟内是不需要再去输入的)

花括号内放多行语句,从上至下匹配,匹配到哪个expect,则执行哪句。

这里如果匹配到第一行会执行第一行;然后第一行的执行结果如果匹配到第二行也会执行第三行;

如果某一行没有匹配到会向下寻找匹配到的那一行进行执行)

注意:多行的expect的{后不要跟语句,否则读不到这条,需要换行后去写具体的期望值和操作。

#!/usr/bin/expect

#

# mimvp.com

# 2016.10.12

expect {

"*assword" {send "mimvp.com\n"}

"*es/no)?*" {send "yes\n"}

"exit" {send "exit\n"}

exp_continue

}

说明:exp_continue表示继续执行下面的expect。

四、shell中调用expect实现自动登录

通过在shell脚本中,执行expect脚本的方式来实现的。

当然可以将shell中定义的一些变量传递给expect脚本作为参数输入。

示例1:shell 调用 expect 脚本,间接调用

#!/bin/bash

#

# mimvp.com

# 2016.10.12

script_tmp="/Users/homer/script_tmp"

if [ ! -d ${script_tmp} ]; then

echo "${script_tmp} is not found"

mkdir -p ${script_tmp}

cd ${script_tmp}

else

cd ${script_tmp}

fi

## expect file

#./scp_remote_server.sh

/Users/homer/script/scp_remote_server.sh

示例2:shell 嵌套 expect 脚本,直接调用(推荐)

#!/bin/bash

#

# mimvp.com

# 2016.10.12

username='mimvp-guest'

passwd='mimvp.com'

passwd2='\$mimvp.com'

/usr/bin/expect <

set timeout 30

spawn /usr/bin/htpasswd -c /etc/squid/passwd $username

## first password

expect {

"*es/no:" { send "yes\n"; exp_continue }

"*assword:" { send "$passwd\n; exp_continue" }

}

## second password to confirm

expect "*assword:"

send "$passwd\n"

spawn ssh mimvp@123.57.78.100

expect {

"*es/no" { send "yes\r"; exp_continue }

"*assword" { send "$passwd2\r" }

}

expect "*#"

send "cd /home/script/\r"

#expect "*#"

#send "svn up\r"

expect "*#"

send "ls -l\r"

expect "*#"

send "exit\r"

#interact

expect eof

EOF

本段脚本,实现了两个功能:

功能1,使用htpasswd命令,输入密码,并再次确认密码

功能2,远程登录服务器,并svn up下载代码,并退出远程服务器

以上脚本,君测试成功!

说明:经过这次尝试些expect,给我的感觉是expect对格式的要求比较高,比如花括号之间必须有空格啊之类的,所以如果有报错,大家可以仔细观察一下是不是语法格式错误了。

expect 更多语法

1. expect中的判断语句

if { condition } {

# do your things

} elseif {

# do your things

} else {

# do your things

}

expect中没有小括号(),所有的if/else, while, for的条件全部使用大括号{}, 并且{ 与左边要有空格,否则会报错。另,else 不能单独占一行,否则会报错。

2. 字符串比较

if { "$node" == "apple" } {

puts "apple"

} elseif { "$node" == "other" } {

puts "invalid name"

exit 70

} else {

puts "asd"

}

对比string,使用==表示相等, !=标示不相等。

3. switch 语句

switch $location {

"apple" { puts "apple" }

"banana" { puts "banana" }

default {

puts "other"

}

记得左大括号{ 的左边要有空格,否则会报错

4. 读取用户输入

expect_user -re "(.*)\n"

send_user "$expect_out(1, string)\n"

expect_user -re 表示正则表达式匹配用户按下回车前输入的所有字符

expect_out(1, string) 表示第一个匹配的内容,即回车前所有字符

expect_out(buffer) 所有的buffer内容

5. break && continue

如c中一样,expect一样可以使用break && continue, 并且功能相同。注:只能用在循环中。

6. 定义交互命令

# stick control + z in variable

set ControlZ \032

# stick control + c in variable

set ControlC \x03

# define string embedded ctrl-z && tab

set oddword foo\032bar\tgorp

五、在远程服务器上配置ssh信任

网上有很多教程,推荐米扑博客:Linux两台主机之间建立信任 (非常经典,验证成功)

感觉长期的话应该比写expect方便,但是我觉得写脚本的话还是最好不要总去操作其他地方,

所以这里我就用expect自己来写的(当然也是想练习一下写expect)

参考推荐:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值