Shell脚本 - Here Document免交互
一、概述
使用I/O
提供重定向的命令,用于替代标准输入免于使用临时文件进行构建输入
并直接生成一共文件并用作命令的标准输入
命令 <<EOF
...
...
EOF
注意事项
- 标记可以使用任意合法字符
- 结尾的标记一定要顶格写,前不能有任何字符
- 结尾的标记前后不能有任何字符及空格,要和开始的标志保持一致
- 开头标记前后的空格会被省略掉
- 输出时加上双引号可以换行
实例
►免交互行数的统计
wc -l <<EOF
1
2
EOF
►免交互读取read命令并打印
无法一次性打印多行
read input <<EOF
hello
bor
EOF
►免交互修改密码
passwd cat <<EOF
123456
123456
EOF
►免交互变量替换
#!/bin/bash
catName=mimi
cat > catHome <<EOF
Cat name is $catName!
EOF
►变量整体免交互赋值
#!/bin/bash
catName=mimi
result=$(cat <<EOF
time is "`date`"
Cat name is $catName!
EOF
)
echo $result
当标记加上单引号或者双引号时变量将不生效
当标记前加上"-"可无视tab键
►多行注释
Here Document
的引入解决多行注释问题
使用":"代表空指令,中间标记区域的内容不会被执行
#!/bin/bash
catName=mimi
: <<EOF
time is "`date`"
Cat name is $catName!
EOF
echo ">3"
二、Expect 自动化交互
建立在TCL
语言基础上的工具,常被用于进化自动化控制和测试,用于解决Shell脚本中交互相关问题
安装方式
rpm -q tcl expect
yum -y install tcl expect
基本命令
①脚本解释器
引入expect
文件
#!/usr/bin/expect
②spawn
表示开启一个会话、启动进程,并跟踪后续的免交互信息
spawn passwd root
③expect
用于判断上一次的输出结果是否包含指定的字符串,有就返回没有就等待超时后返回
只限于不装spawn
启动的进程的输出
用于接收命令后输出,并与期望的字符串进行匹配
④sned
向进程发送字符串,用于模拟用户输入[\r回车|\n]
方式一:
expect "密码" (send "123456\r")
方式二:
expect "密码"
sned "123456\r"
方式三
expect支持多个分支[类似与判断的case]
expect
{
"1" {
send "你"}
"2" {
send "吃"}
"3" {
send "了"}
"4" {
send "吗"}
}
结束符
交互结束等待执行结束,并退回到原用户
expect eof
举例:cat吃了一次粮后,主人认为要下午在喂,当本次喂食结束后,等到下午cat阿巴阿巴的来要吃的
interact
用于保持登录状态,不会退出到原终端
set
设置超时时间
举例:set timeout 30 [s/秒]
exp_continue
用于附加与某个 expect
判断项之后
举例:如果条件为true
时将循环,如果为false
时将会结束
注意:使用exp_continue
时,如果跟踪对象 passwd
这样的输入密码后就结束进程的命令
expect{}
外不要再加上expect eof
,否则会报错
sned_user
相当于回显命令,相当于echo
接收参数
expect
脚本可以接收从bash
命令传递的参数 使用[lindex $argv n]
获得
sed hostname [lindex $argv 0] 相当于 hostname $1
实例
►su延时切换用户
#!/usr/bin/expect
set timeout 5
set username [lindex $argv 0]
set passwd [lindex $argv 1]
spawn su $username
expect "密码" {
send "$passwd\r"}
expect "*]#"
send_user "ok"
#interact
expect_eof
►远程登录并提示成功
#!/usr/bin/expect
spawn ssh [email protected]
expect "echo"
send "登录成功!"
expect eof
►expect嵌入shell
#!/bin/bash
user=$1
password=$2
useradd $user
/usr/bin/expect <<-EOF
spawn passwd $user
espect "新的*"
send "${password}\r"
expect "重新*"
send "${password}\r"
expect eof
EOF
►实现ssh自动登录
#!/usr/bin/expect
set timeout 5
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $hostname
expect {
"No route to host" exit
"Connection refused" exit
"(yes/no)" {
send "yes\r";exp_continue}
"password" {
send "$password\r"}
}
interact
►免交互完成新磁盘创建
#!/bin/bash
file=$1
/usr/bin/expect <<EOF
spawn fdisk $file
expect "命令" {send "n\r"}
expect "Select*" {send "p\r"}
expect "分区号" {send "1\r"}
expect "起始" {send "\r"}
expect "Last" {send "\r"}
expect "命令" {send "w\r"}
expect eof
EOF
#也可以通过过滤获取
#name=`fdisk -l /dev/sdb | egrep '^/dev/' | awk '{print $1}'`
#mkfs.xfs $name -f &> /dev/null
mkfs.xfs $file"1" -f &> /dev/null
if [ $? -eq 0 ];then
read -p "请输入挂载目录:" list
mkdir $list
mount $file"1" $list
#mount $name $list
echo "挂载完毕!"
else
echo "失败!"
fi
►免交互嵌入shell中SSH远程登录
#!/bin/bash
hostname=$1
password=$2
/usr/bin/expect <<EOF
spawn ssh $hostname
expect {
"(yes/no)" {send "yes\r"}
"password" {send "$password\r";;expect eof}
}
interact
EOF