[Shell编程] Shell 编程之免交互

发布于:2025-08-12 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

一、什么是交互?为什么需要免交互?

1️⃣交互的定义

2️⃣Linux 中的交互与免交互

二、Here Document:简单免交互的利器

1️⃣基本语法

2️⃣实用实例

<1>实例 1:用wc -l统计行数

<2>实例 2:read命令免交互

<3>实例 3:passwd设置密码免交互

<4>实例 4:cat命令写入文件(含变量替换)

<5>实例 5:将内容赋值给变量

3️⃣格式控制

<1>关闭变量替换

<2>去掉每行前的 TAB 字符

4️⃣多行注释

三、expect:复杂交互的解决方案

1️⃣安装 expect

2️⃣核心参数与语法

3️⃣实用实例

<1>实例 1:单一分支交互(设置用户密码)

<2>实例 2:多分支交互(ssh自动登录)

四、总结


在 Linux Shell 编程中,自动化运维是核心目标之一。而实现自动化的关键,往往在于免交互—— 让脚本无需人工干预就能完成原本需要手动输入的操作。本文将基于 Shell 编程中免交互的核心知识,从基础概念到具体工具(Here Document 和 expect),带你一步步掌握免交互技巧,适合初学者快速入门。

一、什么是交互?为什么需要免交互?

1️⃣交互的定义

在计算机领域,交互指的是人与计算机通过对话语言(如图形界面、命令行等)进行信息交换的过程。常见的交互方式有图形用户界面(GUI)、命令行界面(CLI)、语音交互等,目的是提高人与计算机的沟通效率。

2️⃣Linux 中的交互与免交互

在 Linux 中,很多操作需要交互:比如passwd设置密码时需要输入两次密码,read命令需要等待用户输入,ssh登录需要输入密码等。

但在自动化运维中,我们希望脚本能 “自己跑”,不需要人工输入 —— 这就是免交互。免交互能减少重复操作,提高效率,是 Shell 脚本自动化的核心能力。

常见的需要免交互处理的命令:readftppasswdsusudofdiskcat等。

二、Here Document:简单免交互的利器

Here Document(简称 “heredoc”)是 Shell 中一种特殊的代码块,通过 I/O 重定向为交互式命令提供输入,无需临时文件,直接 “就地” 生成输入内容。

1️⃣基本语法

bash

命令 << 标记
  内容(标记之间的部分,作为命令的输入)
标记

  • 核心作用:将 “标记之间的内容” 作为标准输入,传递给前面的 “命令”。
  • 标记规则:
    • 标记可以是任意合法字符(常用EOF,即 “End Of File”);
    • 结尾的标记必须顶格写,前面不能有任何字符(包括空格);
    • 结尾的标记后面也不能有任何字符(包括空格);
    • 开头的标记前后的空格会被自动忽略。

2️⃣实用实例

<1>实例 1:用wc -l统计行数

wc -l用于统计行数,结合 heredoc 可直接统计标记内的内容行数:

bash

wc -l << EOF
Line 1
Line 2
Line 3
EOF
# 输出:3(表示有3行内容)
<2>实例 2:read命令免交互

read命令默认需要等待用户输入,用 heredoc 可提前指定输入内容:

bash

#!/bin/bash
read i << EOF
Hi  # 这里的“Hi”会被作为read的输入,赋值给变量i
EOF
echo $i  # 输出:Hi
<3>实例 3:passwd设置密码免交互

passwd命令设置密码时需要输入两次密码,用 heredoc 可自动完成:

bash

#!/bin/bash
passwd jerry << EOF
This_is_password  # 第一次输入密码
This_is_password  # 第二次确认密码(必须与第一次一致)
EOF
<4>实例 4:cat命令写入文件(含变量替换)

用 heredoc 结合cat可向文件写入内容,支持变量替换:

bash

#!/bin/bash
doc_file="2019.txt"  # 定义文件名变量
i="company"  # 定义内容变量
cat > $doc_file << HERE
Take him from home to $i  # 变量$i会被替换为“company”
HERE

# 执行后,2019.txt内容为:Take him from home to company
<5>实例 5:将内容赋值给变量

heredoc 的内容还能直接赋值给变量,再通过echo输出:

bash

#!/bin/bash
ivar="Great!"
myvar=$(cat << EOF
This is Line 1. $ivar  # 变量$ivar会被替换为“Great!”
EOF
)
echo $myvar  # 输出:This is Line 1. Great!

3️⃣格式控制

heredoc 支持两种特殊格式控制,满足更多场景需求:

<1>关闭变量替换

默认情况下,heredoc 会自动替换变量值。如果希望按字符原样输出(不替换变量),给标记加单引号即可:

bash

#!/bin/bash
kgc=100
cat << 'EOF'  # 标记加单引号,关闭变量替换
This is Line 1. $kgc  # $kgc会原样输出,不会变为100
EOF
# 输出:This is Line 1. $kgc
<2>去掉每行前的 TAB 字符

如果内容中每行开头有 TAB 字符(用于缩进),可在标记前加-,自动去除 TAB:

bash

#!/bin/bash
cat <<- 'EOF'  # 标记前加“-”,去除内容中的TAB
	Line 1(前面有TAB)
	Line 2(前面有TAB)
EOF
# 输出:
# Line 1(前面有TAB)
# Line 2(前面有TAB)(TAB被自动去除)

4️⃣多行注释

Shell 默认用#做单行注释,heredoc 可实现多行注释:

bash

#!/bin/bash
kgc=100
: << DO-NOTHING  # “:”是空命令,后面的内容会被忽略(即注释)
这是第一行注释
这是第二行注释
bash不会执行这里的内容
DO-NOTHING
echo $kgc  # 输出:100(注释不影响其他代码)

三、expect:复杂交互的解决方案

Here Document 适合简单交互场景,对于更复杂的交互(如ssh登录、远程操作),需要用expect工具。expect基于 tcl 语言,专门用于自动化控制交互过程。

1️⃣安装 expect

bash

sudo apt install expect  # Ubuntu/Debian
# 或
sudo yum install expect  # CentOS/RHEL

2️⃣核心参数与语法

expect 脚本的核心是 “匹配输出→发送输入”,关键参数如下:

参数 / 命令 作用
#!/usr/bin/expect 脚本解释器,表明这是 expect 脚本
spawn 启动一个进程(如sshpasswd),并跟踪其交互信息
expect "字符串" 等待进程输出包含 “字符串” 的内容
send "内容\r" 向进程发送 “内容”,\r表示回车(必须加)
expect eof 等待进程执行结束(脚本结束)
interact 执行完后保持交互状态(手动操作)
set timeout N 设置超时时间(N 秒,-1表示永不超时)
exp_continue 继续匹配后续内容(不退出当前 expect 块)
send_user "信息" 输出信息到终端(类似echo
[lindex $argv n] 接收外部参数(n 从 0 开始,0 是第一个参数)

3️⃣实用实例

<1>实例 1:单一分支交互(设置用户密码)

bash

#!/bin/bash
user="mtt"
password="nt"
useradd $user  # 先创建用户

# 用expect处理passwd的交互
expect << EOF
spawn passwd $user  # 启动passwd进程,跟踪交互
expect "New password:"  # 等待输出“New password:”
send "$password\r"  # 发送密码
expect "Retype new password:"  # 等待输出“Retype new password:”
send "$password\r"  # 发送确认密码
expect eof  # 等待进程结束
EOF
<2>实例 2:多分支交互(ssh自动登录)

ssh登录可能遇到多种场景(首次登录需确认、输入密码、连接失败等),用多分支处理:

bash

#!/usr/bin/expect
set timeout 30  # 超时时间30秒
set hostname [lindex $argv 0]  # 接收第一个参数(目标主机)
set password [lindex $argv 1]  # 接收第二个参数(密码)

spawn ssh $hostname  # 启动ssh进程

expect {
  "Connection refused" { exit }  # 连接被拒绝,退出
  "Name or service not known" { exit }  # 主机不存在,退出
  "Are you sure you want to continue connecting (yes/no)?" {  # 首次登录确认
    send "yes\r"
    exp_continue  # 继续匹配后续内容
  }
  "password:" { send "$password\r" }  # 输入密码
}

interact  # 登录后保持交互(可手动操作)

执行脚本:

bash

./expect_auto_ssh.sh 192.168.141.130 abc123  # 主机IP+密码作为参数

四、总结

免交互是 Shell 自动化运维的核心技能,掌握这两种工具能大幅提升脚本效率:

  • Here Document:适合简单交互(readpasswd、文件写入),语法简洁,无需额外安装。
  • expect:适合复杂交互(ssh、远程操作),功能强大,需要提前安装。