赞
踩
目录
2.3 interact与expect eof区别演示(免交互ssh主机)
Here Document 是标准输入的一种替代品,使用I/O重定向的方式将命令列表提供给交互式程序 ,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个文件并用作命令的标准输入,Here Document 可以与非交互式程序和命令一起使用。
语法格式:
- 命令 << 标记
- ....
- ......
- 标记
示例:
使用Here Document结合重定向符号>或>>来将多行文本重定向到文件。
- [root@localhost ~]# cat > file.txt << eof
- > 1
- > 2
- > eof
- [root@localhost ~]# cat file.txt
- 1
- 2
在上面的示例中,cat > file.txt 表示将输入重定向到 file.txt 文件中。<< oef 表示开始 Here Document,eof 表示结束 Here Document。文本块中的内容会被作为输入传递给 cat 命令,并写入到 file.txt 文件中。当然 cat > file.txt << eof 也可以写成 cat << eof > file.txt。
注意也可以写成<< EOF,同时结束也要写EOF;如果不指定文件,结束后内容将打印在当前屏幕上。
如果你想追加文本到文件而不是覆盖原有内容,可以使用重定向符号 >>
- [root@localhost ~]# cat >> file.txt << eof
- > a
- > b
- > eof
- [root@localhost ~]# cat file.txt
- 1
- 2
- a
- b
cat >> file.txt 表示将输入追加到 file.txt 文件中,而不是覆盖原有内容。
可以根据需要自由选择文件名和分隔符。确保开始和结束的分隔符(大小写)相同,并且没有特殊含义。注意,如果结束符eof后存在空格,将没有结束功能,默认为文本内容。
应用:
使用 wc -l 命令后面直接跟文件名就可以统计文件内有多少行内容,将要统计的内容置于标记“EOF” 之间,直接将内容传给 wc -l 来统计。
- [root@localhost opt]# vim wc.sh
- #!/bin/bash
- wc -l << EOF
- line 1
- line 2
- EOF
- [root@localhost opt]# bash wc.sh
- 2
使用 passwd 命令设置密码,EOF 标记之间的两行是输入的密码和确认密码,两行内容必须保持一致,否则密码设置不成功。此脚本执行后不会输出任何信息,可另开一个终端登录用户,输入新修改的密码来验证密码是否修改正确。
- [root@localhost opt]# passwd fql << eof
- > 123
- > 123
- > eof
- 更改用户 fql 的密码 。
- 新的 密码:无效的密码: 密码少于 8 个字符
- 重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
Here Document 变量设定:
Here Document 也支持使用变量,如果标记之间有变量被使用,会先替换变量值。如果想要将一些内容写入文件,除了常规的方法外,也可以使用 Here Document。如果写入的内容中包含变量,在写入文件时要先将变量替换成实际值,在结合 cat 命令完成写入。
- [root@localhost opt]# name=zhangsan;age=20
- [root@localhost opt]# cat << eof
- > Name=$name
- > Age=$age
- > eof
- Name=zhangsan
- Age=20
定义了两个变量:name 和 age。然后,使用 Here Document 将包含这些变量值的文本传递给 cat 命令。 如果希望在Here Document中保留变量的字面值而不进行替换,可以使用单引号或双引号来括住 Here Document 的开始标记,即 cat << 'eof',在这种情况下,输出将保留 $name 和 $age 作为字面文本,而不会被替换为变量的实际值。
tee 命令将标准输入复制到每个指定文件,并显示到标准输出。相较于 cat >,tee 后面可以直接跟文件名,不需要重定向直接输出。当需要追加内容时,需要使用-a选项。
- [root@localhost opt]# tee file.txt << eof
- > 1
- > 2
- > eof
- 1
- 2
- [root@localhost opt]# cat file.txt
- 1
- 2
是建立在tcl(tool command language)语言基础上的一个工具,它不同于 bash,常被用于进行自动化控制和测试,解决 shell 脚本中交互的相关问题。工具需要安装。
格式:
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
① 脚本解释器:expect 脚本中首先引入文件,表明使用的是哪一种shell。expect的为:/usr/bin/expect
② spawn命令:用于捕捉关键词,后面常跟一个linux执行命令
③ expect命令:用于判断上层捕捉输出的结果是否有指定字符,有则立即返回,没有则默认等待10s
④ exp_continue命令:expect多分支判断时使用
⑤ send命令:expect命令判断完成需要返回时,发送需要交互的指令,想要传递给电脑的文字或字符,该命令不能自动回车换行,\n和\r是回车
⑥ set命令:可用于设置变量、设置expect超时时间,默认是10s,例set time out 30
⑦ set设置位置变量:set password [lindex $argv 0] ,设置时从0开始,执行脚本时在脚本后跟参数即可
⑧ 结束符:(1) expect eof 结束并返回原来环境,原来主机
(2) interact 结束但是不会返回原来的地方,保持当前状态,当前主机
示例:
- [root@localhost opt]# expect
- expect1.1> expect "fql" {send "hi"}
- fql
- hiexpect1.2>
- # > expect捕捉屏幕上的输出,只要出现“hi”,发送后面的语句
应用:免交互传输文件,远程拷贝
- [root@localhost opt]# vim test
- #!/usr/bin/expect
- spawn scp /etc/passwd 192.168.190.101:/opt
- #监控scp命令,出现scp命令开始捕捉屏幕内容
- expect {
- "yes/no" {send "yes\n";exp_continue}
- "password" {send "123123\n";}
- }
- #捕捉屏幕上的关键字,出现yes/no,输入yes。exp_continue代表继续捕捉password,出现password 输入密码;\n\r回车
- expect eof
- #代表结束
-
- [root@localhost ~]# expect test
- spawn scp /etc/passwd 192.168.190.101:/opt
- The authenticity of host '192.168.190.101 (192.168.190.101)' can't be established.
- ECDSA key fingerprint is SHA256:aIqKteFz37bh8tOF7A07YElsVqfHgBSbxwkKXK9dfks.
- ECDSA key fingerprint is MD5:9c:5a:7f:ec:d9:0c:2a:b2:9d:9e:03:77:f3:87:36:d4.
- Are you sure you want to continue connecting (yes/no)? yes
- Warning: Permanently added '192.168.190.101' (ECDSA) to the list of known hosts.
- root@192.168.190.101's password:
- passwd 100% 2101 722.5KB/s 00:00
-
- 192.168.190.101
- [root@localhost opt]# ll
- 总用量 4
- -rw-r--r--. 1 root root 2101 1月 31 16:36 passwd

- #!/usr/bin/expect
- spawn ssh 192.168.190.101
- expect {
- "yes/no" {send "yes\n";exp_continue}
- "password" {send "123123\n";}
- }
- expect eof
- #interact
-
- [root@localhost ~]# expect test1
- spawn ssh 192.168.190.101
- The authenticity of host '192.168.190.101 (192.168.190.101)' can't be established.
- ECDSA key fingerprint is SHA256:aIqKteFz37bh8tOF7A07YElsVqfHgBSbxwkKXK9dfks.
- ECDSA key fingerprint is MD5:9c:5a:7f:ec:d9:0c:2a:b2:9d:9e:03:77:f3:87:36:d4.
- Are you sure you want to continue connecting (yes/no)? yes
- Warning: Permanently added '192.168.190.101' (ECDSA) to the list of known hosts.
- root@192.168.190.101's password:
- Last login: Wed Jan 31 16:37:35 2024 from 192.168.190.1
- [root@localhost ~]# [root@localhost ~]#
- #默认10秒钟返回
- 如果配置改为interact,则不会返回

- [root@localhost opt]# vim passwd
- #!/bin/bash
- ip="192.168.190"
- hostlist="
- 101
- 102
- "
- pass=123123
-
- for i in $hostlist
- do
- /usr/bin/expect << EOF
- spawn ssh ${ip}.${i}
- expect {
- "yes/no" {send "yes\r";exp_continue}
- "password" {send "$pass\r"}
- }
- expect "*]#" { send "useradd test\n" }
- expect "*]#" { send "echo 123123 | passwd --stdin test\r" }
- expect "*]#" { send "exit\r" }
- expect eof
- EOF
- done
- [root@localhost opt]# bash passwd
-
- 192.168.190.101:
- [root@localhost ~]# id test
- uid=1001(test) gid=1001(test) 组=1001(test)
- 192.168.190.102:
- [root@localhost ~]# id test
- uid=1001(test) gid=1001(test) 组=1001(test)

取字符串的长度
${#var}:返回字符串变量var的字符的长度,一个汉字算一个字符
- [root@localhost opt]# str=`echo {a..z} | tr -d " "`
- [root@localhost opt]# echo ${#str} #str变量里一共有26个字符
- 26
- [root@localhost opt]# str=123你好
- [root@localhost opt]# echo ${#str}
- 5
跳过左边的字符
${var:offset}
#返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)
${var:offset:number}
#返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分
- [root@localhost opt]# echo ${str}
- abcdefghijklmnopqrstuvwxyz
- [root@localhost opt]# echo ${str:2:3} #跳过前两个往后取三个
- cde
- [root@localhost opt]# echo ${str: -2} #取后两个
- yz
掐头去尾
${var:offset:-length}
#从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容,即:掐头去尾
- [root@localhost opt]# echo ${str:3:-3} #去掉前后三个,取中间
- defghijklmnopqrstuvw
取倒数的范围
${var: -length:-offset}
#先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:-length前空格,并且length必须大于offset
- [root@localhost opt]# echo ${str: -5:-3}
- vw #倒数5个到,倒数3个
删左留右
${var#*word}
#其中word可以是指定的任意字符,自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以第一个word为界删左留右#同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容,即贪婪模
式,以最后一个word为界删左留右
${var##*word}
- [root@localhost ~]# url="http://www.baidu.com/index.html"
- [root@localhost ~]# echo ${url#*/}
- /www.baidu.com/index.html
- #慵懒模式。从左边开始匹配,遇到/就把/左边的都删除包括/本身
- [root@localhost ~]# echo ${url##*/}
- index.html
- #贪婪模式。一直匹配到最后一个/
删右留左
${var%word*}
#其中word可以是指定的任意字符,功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以从右向左的第一个word为界删右留左
${var%%word*}
#同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符,即贪婪模式,以从右向左的最后一个word为界删右留左
- [root@localhost ~]# url="http://www.baidu.com:8080/index.html"
- [root@localhost ~]# echo ${url%:*}
- http://www.baidu.com
- [root@localhost ~]# echo ${url%%:*}
- http
${var/pattern/substr}
${变量/搜索的字符串/修改的字符串}
#查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之
- [root@localhost ~]# user=`grep fql /etc/passwd`
- [root@localhost ~]# echo ${user}
- fql:x:1000:1000:fql:/home/fql:/bin/bash
- [root@localhost ~]# echo ${user/fql/aaa}
- aaa:x:1000:1000:fql:/home/fql:/bin/bash
${var//pattern/substr}
#查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之
- [root@localhost ~]# echo ${user//fql/aaa}
- aaa:x:1000:1000:aaa:/home/aaa:/bin/bash
${var/#pattern/substr}
#查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之
在此处#代表开头,不支持贪婪模式
- [root@localhost ~]# echo ${user/#fql/aaa}
- aaa:x:1000:1000:fql:/home/fql:/bin/bash
${var/%pattern/substr}
#查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之
在此处 % 代表结尾,不支持贪婪模式
- [root@localhost ~]# echo ${user/%bash/nologin}
- fql:x:1000:1000:fql:/home/fql:/bin/nologin
${var/pattern}
#删除var表示的字符串中第一次被pattern匹配到的字符串
- [root@localhost ~]# user=`grep fql /etc/passwd`
- [root@localhost ~]# echo ${user/fql}
- :x:1000:1000:fql:/home/fql:/bin/bash
${var//pattern}
删除var表示的字符串中所有被pattern匹配到的字符串
- [root@localhost ~]# echo ${user//fql}
- :x:1000:1000::/home/:/bin/bash
${var/#pattern}
删除var表示的字符串中所有以pattern为行首匹配到的字符串
- [root@localhost ~]# echo ${user/#fql}
- :x:1000:1000:fql:/home/fql:/bin/bash
${var/%pattern}
删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
- [root@localhost ~]# echo ${user/%bash}
- fql:x:1000:1000:fql:/home/fql:/bin/
${var^^}:把var中的所有小写字母转换为大写
${var,,}:把var中的所有大写字母转换为小写
- [root@localhost ~]# a=aBc
- [root@localhost ~]# echo ${a^^}
- ABC
- [root@localhost ~]# echo ${a,,}
- abc
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。