当前位置: 首页 > article >正文

【shell】多行重定向与免交互expect与ssh、scp的结合使用

目录

一、多行重定向

举例1:使用read命令接收用户的输入值会有交互过程

 举例2:设置变量的值

举例3:创建用户密码 

举例4:使用多行重定向写入文件中(以repo文件举例)

举例5:变量设定

二、免交互expect

ssh连接免交互 

定义变量

​编辑 使用位置变量的方式

测试题:给3台主机都创建test用户,并生成密码


一、多行重定向

可以理解为这是标准输入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,可以直接产生一个文件,输入文件信息,常与非交互程序和命令一起使用

语法格式

命令<<   标记

....

......

标记

注意事项:

1、表示可以使用任意的合法字符(通用的字符是EOF表示end of file)

2、结尾的标记是一定要顶格写,前面不能有任何字符(包括空格)

3、结尾的标记后面也不能有任何字符(包括空格)

4、开头标记前后空格会被省略掉

5、单引号变量双引号

举例1:使用read命令接收用户的输入值会有交互过程

[root@localhost test]#read i <<EOF
> 10
> EOF
[root@localhost test]#echo $i
10

 举例2:设置变量的值

举例3:创建用户密码 

举例4:使用多行重定向写入文件中(以repo文件举例)

[root@localhost cs]#cat repo.sh 
#!/bin/bash
cat > /cs/http.repo <<EOF
[http]
name=http
baseurl=http://192.168.20.8/
gpgcheck=0
EOF

举例5:变量设定

Here Document 也支持使用变量,如果标记之间有变量被使用,会先替换变量值。如 果想要将一些内容写入文件,除了常规的方法外,也可以使用 Here Document。如果写入 的内容中包含变量,在写入文件时要先将变量替换成实际值,在结合 cat 命令完成写入。

[root@localhost cs]#cat repo.sh 
#!/bin/bash
ip="192.168.20.8"
filename="http.repo"
cat > /cs/${filename} <<EOF
[http]
name=http
baseurl=http://${ip}/
gpgcheck=0
EOF
[root@localhost cs]#bash repo.sh 
[root@localhost cs]#ls
http.repo  local.repo  repo.sh
[root@localhost cs]#cat http.repo 
[http]
name=http
baseurl=http://192.168.20.8/
gpgcheck=0

EOF加上双引号,表示对重定向内容的变量强引用 

二、免交互expect

定义:

是建立在tcl(tool command language)语言基础上的一个工具,常被用于进行自动化控制和测试,解决shell脚本中交互的相关问题

基本命令:

(1)脚本解释器

expect 脚本中首先引入文件,表明使用的事哪一种shell

#!/usr/bin/expect

(2)spawn

spawn 后面通常跟一个Linux执行命令,表示开启一个会话、进程,并跟踪后续交互信息

例: spawn passwd root

(3)expect

判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回;只能捕捉有swpan启动的进程输出;用于接受命令执行后的输出,然后和期望的字符串匹配

(4)send

向进程发送字符串,用于模拟用户的输入,该命令不能自动回车换行,要加 \r (回车) 或者\ n

学习相关的命令

spawn  ##表示开启监控、捕捉模式,后面跟着命令,如ssh,scp等
expect  ##表示开始捕捉,即是从进程开始接收字符串,后面是花括号,表示捕捉的内容{}
send  ##表示遇到捕捉的关键字,send免交互要做的事,即向进程发送字符串
exp_continue ##表示继续捕捉,一般是连续的操作,比如向ssh需要先回答yes,然后继续捕捉password
expect eof ##表示停留10秒以后,自动退出,与spawn相对应
interact  ##表示停留,不再退出

ssh连接免交互 

[root@localhost cs]#cat ssh.txt 
#!/usr/bin/expect
spawn ssh 192.168.20.8   ##spawn表示开启捕捉模式
expect {                 ##expect表示开始捕捉
"yes/no" {send "yes\n";exp_continue }
"password" {send "123\n"}##yes/no以及password为捕捉关键字
}
expect eof   ##表示停留10秒退出

(5) 结束符

expect eof

表示交互结束,等待执行结束,退回到原用户,与spawn对应

比如切换到root用户,expect 脚本默认的等待时间是10s,当执行王命令后,默认停留10s后,自动切回原用户.

interact

执行完成后保持交互状态, 把控制权交给控制台,会停留在目标终端而不是退回到原终端,这时候就可以手工操作了,interact后命令不再起作用,比如interact后添加exit,并不会退出root用户。而如果没有interact则登录完成后会退出,而不是留在远程终端上。

使用interact会保持在终端而不会退回原终端,比如切换到root用户,会一直在root用户状态下;比如ssh到另一台服务器,会一直在目标服务器终端而不会切回原服务器。

需要注意的是,expect eof 与 interact 只能二选一。

(6)set

expect 默认的超时时间是10秒,通过set 命令可以设置会话超时时间,若不限制超时时间则应设置为-1

例子: set timeout 30  set ip 192.168.20.30 set user root

定义变量

[root@localhost cs]#cat ssh.txt 
#!/usr/bin/expect
set ip 192.168.20.8    ##设置 ip变量
set user root          ##设置user变量
set id lisi            ##设置id变量
set pass 123           ##设置pass变量
spawn ssh ${user}@${ip}
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "${pass}\n"}
}
expect "#" {send "useradd ${id}\n"}
expect "#" {send "echo ${pass}|passwd ${id} --stdin\n"}
expect eof  ##所有事干完再退出

[root@localhost cs]#cat ssh.txt 
#!/usr/bin/expect
set ip 192.168.20.8
set user root
set id lisi
set pass 123
spawn ssh ${user}@${ip}
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "${pass}\n"}
}
expect "#" {send "useradd ${id}\n"}
expect "#" {send "echo ${pass}|passwd ${id} --stdin\n"}
expect "#" {send "exit\n"}   ##表示退出
interact   ##等待一切都回到原本的控制台再结束

 使用位置变量的方式

#!/usr/bin/expect
#参数传入
set host  [lindex $argv 0]  #理解为host=$1

set pass  [lindex $argv 1]  #理解为pass=$2

spawn su $host  #开始追踪命令
expect "密码:" {send "$pass\n"}
#免交互执行,捕捉信息并匹配
expect "$" {send "echo hello\n"} 
##send_user "hello"    ##send_user表示回显命令与echo相同  
#把控制权交给控制台
expect "$" {send "exit\n"}
interact
#expect eof

测试题:给3台主机都创建test用户,并生成密码

[root@localhost cs]#cat test.sh 
#!/bin/bash
net="192.168.20."
pass=123
host="
6
8
18
10
"
for i in $host
do
ip=${net}${i}
/usr/bin/expect <<EOF
spawn ssh ${ip}
expect {
"yes/no" {send "yes\n";exp_continue }
"password" {send "${pass}\n"}
}
expect "#" {send "useradd test\n"}
expect "#" {send "echo ${pass}|passwd test --stdin\n"}
expect "#" {send "exit\n"}
interact
EOF
done

 

 


http://www.kler.cn/a/158553.html

相关文章:

  • macbook外接2k/1080p显示器调试经验
  • 【蓝桥杯C/C++】I/O优化技巧:cin.tie(nullptr)的详解与应用
  • 环形缓冲区 之 STM32 串口接收的实现
  • MongoDB聚合操作
  • 【经验分享】2024年11月下半年软件设计师考试选择题估分(持续更新~~)
  • 为何数据库推荐将IPv4地址存储为32位整数而非字符串?
  • vue3 vue-router过渡动效 滚动行为 (四)
  • 使用rust slint开发桌面应用
  • Docker 容器日志查看和清理
  • Python自动化——driver.switch_to的用法
  • 解析生效探测方法
  • 超大规模集成电路设计----CMOS反相器(五)
  • 整体迁移SVN仓库到新的windows服务器
  • 住宅IP代理如何选择?如何识别高质量的住宅IP代理服务商
  • 数据库锁的设计
  • 内部文件上传以及渲染-接口API
  • 技巧-PyTorch中num_works的作用和实验测试
  • 深度学习|keras编程基础
  • 更换cmd下默认选择Python解释器
  • Rust的From与Into Trait
  • 对标Gen-2!Meta发布新模型,进军文生视频赛道
  • 使用晶振遇到的两个问题
  • .NET微信网页开发相关文章教程
  • 电脑上mp4视频文件无缩略图怎么办
  • 在python的Scikit-learn库中,可以使用train_test_split函数来划分训练集和测试集。
  • Servlet基础知识