ubuntu使用expect脚本让远端服务器自动执行相关命令,以及使用ssh远程执行sh脚本或shell命令块

2 篇文章 0 订阅

expect是什么

expect是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。说白了,expect就是一套用来实现自动交互功能的软件。

在实际工作中,我们运行命令、脚本或程序时,这些命令、脚本或程序都需要从终端输入某些继续运行的指令,而这些输入都需要人为的手工进行。而利用expect,则可以根据程序的提示,模拟标准输入提供给程序,从而实现自动化交互执行。这就是expect!!!

在使用expect时,基本上都是和以下四个命令打交道:

send 用于向进程发送字符串
expect 从进程接收字符串
spawn 启动新的进程
interact 允许用户交互

  • send命令接收一个字符串参数,并将该参数发送到进程。
  • expect命令和send命令相反,expect通常用来等待一个进程的反馈,我们根据进程的反馈,再发送对应的交互命令。
  • spawn命令用来启动新的进程,spawn后的send和expect命令都是和使用spawn打开的进程进行交互。
  • interact命令用的其实不是很多,一般情况下使用spawn、send和expect命令就可以很好的完成我们的任务;但在一些特殊场合下还是需要使用interact命令的,interact命令主要用于退出自动化,进入人工交互。比如我们使用spawn、send和expect命令完成了ftp登陆主机,执行下载文件任务,但是我们希望在文件下载结束以后,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,此时使用interact命令就可以很好的完成这个任务。

声明expect脚本

查看expect脚本的路径,然后在expect脚本文件第一行声明,类似bash脚本
在这里插入图片描述

#!/usr/bin/expect

自动ssh登录demo

#!/usr/tcl/bin/expect

set timeout 30	#设置超时时间
set host "101.200.241.109"	#设置变量
set username "root"			#设置变量
set password "123456"		#设置变量

spawn ssh $username@$host	#给ssh运行进程加个壳,用来传递交互指令
expect "*password*" {send "$password\r"}	#期待上一行命令返回的结果中包含password字符串,*类似redis中keys寻找key,匹配任务数量的任意字符
interact					#没有这一句登录完成后会退出,而不是留在远程终端上

脚本中的各项参数解释

  • set timeout 30
    设置超时时间,单位为秒,默认情况下是10秒
  • set host "101.200.241.109"
    设置变量
  • spawn ssh $username@$host
    是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。它主要的功能是给ssh运行进程加个壳,用来传递交互指令
  • expect "*password*" {send "$password\r"}
    这里的expect也是expect的一个内部命令,这个命令的意思是判断上次输出结果里是否包含“password”的字符串,如果有则立即返回否则就等待一段时间后返回这里等待时长就是前面设置的30秒,这里这个expect看起来似乎是支持正则的,其实就是期待上一行命令的返回结果是不是预期的,是预期的时候才执行下一步;然后后面跟着的 {send "$password\r"}意味着,上一行命令返回包含password的字符串的时候,去执行.类似if.最后有一个\r不要忘记了,意味的命令输入完之后的回车.
  • interact
    执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上

expect脚本传参demo

#!/usr/bin/expect

if {$argc < 3} {
    puts "Usage:cmd <host> <username> <password>"
    exit 1
}

set timeout -1
set host [lindex $argv 0] 
set username [lindex $argv 1]
set password [lindex $argv 2]

spawn ssh $username@$host
expect "*password*" {send "$password\r"}
interact

脚本中的参数解释
expect中,$argc表示参数个数,而参数值存放在$argv中,比如取第一个参数就是[lindex $argv 0],以此类推。

但是expect中发送执行脚本命令给远端服务器的时候会发现,被执行的脚本中的相对路径会报不存在.需要改成绝对路径(全路径).这个时候就需要在远端服务器上ssh执行代码块了

expect参考了大佬的文章
https://www.jianshu.com/p/bbe9949e2562

ssh在远端服务器上执行脚本或者shell命令代码块

前提需要配置ssh免密登录,这个可以参考我另一篇博文
https://blog.csdn.net/weixin_43944305/article/details/103288482

如果是简单执行几个命令,则:

ssh user@remoteIp "cd /home ; ls;"

几个注意的点:

  • 双引号,必须有。如果不加双引号,第二个ls命令在本地执行
  • 分号,两个命令之间用分号隔开

如果要执行的命令比较多,可能一行写不下,这个事就可以使用<<来达到执行代码块的目的了

sh脚本执行代码块或者执行远程服务器上的脚本demo

  • 事先最好使用ssh公私钥实现免密ssh登录,具体可以参考我另一篇文章https://blog.csdn.net/weixin_43944305/article/details/103288482
  • 执行的命令在<< gggg之间,这个gg可以自定义
  • > /dev/null 2>&1重定向目的在于不显示远程的输出了,/dev/null 这个设备,是linux中黑洞设备,什么信息只要输出给这个设备,都会给吃掉;2>&1代表将错误输出2绑定给正确输出1,然后将正确输出发送给 /dev/null设备
  • 在结束前,加exit退出远程节点
#!/bin/bash
ssh user@remoteNode > /dev/null 2>&1 << gg
cd /home
touch abcdefg.txt
./xxx.sh &	#有运行权限的话直接执行; '&'类似nohup的'&'使脚本在后台自动运行
exit
gg
echo done!
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值