目录
概念
在计算机科学和信息技术领域,"交互"和"免交互"通常用来描述程序或系统与用户之间的互动方式。这两个概念可以用来解释不同类型的软件、系统和应用程序。
交互(Interactive):
-
交互是指用户与程序或系统之间进行双向通信,用户可以输入指令、数据或请求,程序或系统会做出相应的反馈和响应。这种互动通常需要用户的主动参与,例如,通过键盘、鼠标、触摸屏等方式与计算机进行交流。
-
交互性软件或系统通常需要用户的实时操作和反馈,以满足用户需求或执行用户指令。示例包括图形用户界面(GUI)应用程序、游戏、网页应用程序等。
免交互(Non-Interactive):
-
免交互是指程序或系统在不需要用户直接参与的情况下执行任务或操作。这意味着程序能够自动化执行预定的任务,而不需要用户的干预或输入。
-
免交互软件或系统通常用于自动化、批处理、脚本执行等场景,其中操作步骤被预先定义,程序可以按照这些定义执行操作。示例包括自动化脚本、批处理文件、服务器管理工具等。
在实际应用中,交互性和免交互性可以结合使用,根据具体需求来设计和开发软件和系统。例如,一个系统可能允许用户手动交互,同时还能执行定期的自动化任务以提高效率。不同的应用场景和任务可能需要不同程度的交互和自动化。
使用
使用Shell脚本:
-
可以编写Shell脚本来自动执行一系列命令或任务。在脚本中,可以预定义所有需要执行的命令,然后运行该脚本,它将按照定义执行这些任务。
-
输入/输出重定向:
- 使用输入重定向
<
和输出重定向>
操作符,可以将命令的输入和输出从文件中读取和写入,而无需人工交互。例如:
command < input.txt command > output.txt
- 使用输入重定向
使用SSH批处理:
- 如果需要自动化执行远程服务器上的任务,可以使用SSH批处理脚本。这允许在远程服务器上运行命令,而无需手动登录和执行。
Here Document:
它允许定义一个文本块,而不需要手动输入每一行,这在自动化脚本和批处理中非常有用。Here Document 使用 <<
操作符来定义文本块的开始标记,通常命名为 "EOF"(End of File),然后在结束标记出现之前,所有文本都将作为命令的输入。
以下是Here Document的详细解释和示例:
Here Document的语法:
command << EOF
This is the input text
More lines of input
EOF
-
command
:要执行的命令或脚本。 -
<< EOF
:这是文本块的开始标记,通常命名为 "EOF",但可以选择其他名称。 -
文本块:要传递给命令的多行文本,直到遇到 "EOF" 结束标记。
-
EOF
:这是结束标记,用于指示文本块的结束。示例1:使用Here Document执行命令
cat << EOM
This is line 1.
This is line 2.
EOM
上述示例会将两行文本作为 cat
命令的输入,输出结果将显示这两行文本。
示例2:使用Here Document传递变量
还可以在Here Document中传递变量的值。例如:
name="John"
cat << EOM
Hello, $name!
This is a Here Document example.
EOM
此示例中,Here Document 中的 $name
将被替换为变量 "John" 的值。
示例3:将Here Document输出到文件
还可以将Here Document的内容重定向到文件,而不是将其传递给命令。例如:
cat << EOM > output.txt
This is line 1.
This is line 2.
EOM
上述示例会将Here Document 的内容写入名为 "output.txt" 的文件。
使用expect工具:
- timeout: 设置等待的超时时间(以秒为单位)。如果在指定的时间内没有匹配到期望的文本,
expect
将执行超时操作。默认超时时间是10秒。您可以使用set
命令来更改默认的超时时间,例如:
set timeout 30
expect 是一种自动化工具,用于自动化交互式任务。它通常用于模拟用户的键盘输入和对命令行输出的响应,以执行一系列任务,而不需要实际的人工干预。expect 基于Tcl编程语言,并提供了强大的功能来处理交互式场景。以下是对expect的详细解释以及一个简单的示例:
expect
的基本语法:
expect
的操作步骤通常包括以下几个关键部分:
-
引入
expect
: 首先,在脚本的开头,您需要引入expect
,这可以通过在脚本的第一行添加#!/usr/bin/expect
来实现。这将告诉系统使用expect
来执行脚本。 -
定义变量: 在
expect
脚本中,通常需要定义一些变量,以存储用户名、密码、服务器地址或其他需要的数据。这些变量将用于后续的操作。 -
使用
spawn
启动交互进程: 使用spawn
命令来启动需要进行交互的进程,例如 SSH 连接到远程服务器或其他交互式应用程序。这个命令会启动目标进程并创建一个与之关联的伪终端。 -
使用
expect
匹配文本: 使用expect
命令来等待目标进程的输出,并在匹配特定文本时执行操作。在expect
命令中,您提供要匹配的文本,通常是提示符、命令输出或其他交互式场景中的文本。 -
使用
send
发送数据: 当expect
匹配到文本时,您可以使用send
命令来发送数据,例如用户名、密码、命令或其他输入。通常,您需要包括回车符(\r
)来模拟用户按下“Enter”键。 -
重复
expect
和send
步骤: 根据需要,您可以多次使用expect
和send
来执行多个交互步骤。例如,在登录到远程服务器后,您可能需要执行多个命令或操作。 -
处理错误和异常: 考虑添加错误处理和异常处理机制,以应对可能出现的问题,例如登录失败、连接超时等情况。
-
结束脚本: 最后,通常会使用
expect eof
来等待目标进程的结束,以确保所有操作已完成,然后退出脚本。或者使用interact
来保留操作,结束符号二选一,不可同时使用
#!/usr/bin/expect
expect "匹配的文本" {
操作1
操作2
...
}
# !/usr/bin/expect 必须声明解析器
-
expect
后面跟着要匹配(捕获)的文本,可以是一个命令的输出、提示符或其他交互式场景中的文本。 -
接着是一对花括号
{}
,在其中包含一系列操作,这些操作将在匹配文本出现时执行。
expect 的简单示例:
以下是一个简单的 expect
示例,它使用 expect
来登录到远程服务器并执行一些命令。
#!/usr/bin/expect
set username "your_username"
set password "your_password"
set server "remote_server_ip"
spawn ssh $username@$server
expect "password: "
send "$password\r"
expect "$username@.*"
send "ls -l\r"
expect "$username@.*"
send "exit\r"
expect eof
这个示例的解释如下:
-
引入
expect
。 -
定义登录所需的用户名、密码和远程服务器地址。
-
使用
spawn
命令启动SSH连接。 -
第一个
expect
匹配密码提示符,然后使用send
命令发送密码。 -
第二个
expect
匹配登录后的命令行提示符,然后发送ls -l
命令来列出文件。 -
第三个
expect
匹配提示符,然后发送exit
命令以退出SSH会话。 -
最后一个
expect
匹配会话结束符(eof),以确保已经完成了所有操作。
参数设置
- set timeout: 设置等待的超时时间(以秒为单位)。如果在指定的时间内没有匹配到期望的文本,
expect
将执行超时操作。默认超时时间是10秒。您可以使用set
命令来更改默认的超时时间,例如:
set timeout 30
-
exp_continue
它用于告诉
expect
继续等待匹配的文本,并执行相应的操作,而不是终止脚本执行。通常,exp_continue
被用于创建循环等待某些文本的操作,以处理多次出现的交互式情况。以下是
exp_continue
的基本用法和示例:基本用法:
expect {
"文本1" {
操作1
exp_continue
}
"文本2" {
操作2
exp_continue
}
"文本3" {
操作3
}
}
在上面的示例中,expect
会等待出现 "文本1"、"文本2" 或 "文本3" 中的任何一个,根据匹配的文本执行相应的操作。使用 exp_continue
来告诉 expect
在执行完操作后继续等待匹配的文本。
- send_user
用于向控制台输出文本信息。它允许将信息发送到脚本执行时的标准输出(通常是终端或命令行界面),而不是将信息发送到被控制的交互式进程。
基本格式:
send_user "输出的文本信息"
send_user
的作用类似于在其他编程语言中用于输出信息的命令,比如 print
或 echo
。它不会影响与被控制的进程之间的交互,而只是将信息输出到控制台。
示例:
send_user "开始执行脚本...\n"
在这个示例中,send_user
将会向控制台输出 "开始执行脚本…" 的信息,并在末尾添加一个换行符(\n
)以换行。
- 接受参数
参数的传递方式与在普通的 Bash 脚本中有些不同。expect
使用 argv
数组来接收参数,而不是像 Bash 中使用 $1
、$2
等。
以下是在 expect
脚本中接受命令行参数的基本方式:
set 参数1 [lindex $argv 0]
set 参数2 [lindex $argv 1]
# 继续设置其他参数...
# 使用参数进行操作
在上面的代码中,我们首先使用 lindex
函数从 argv
数组中获取参数的值,然后将其存储在变量中供脚本后续使用。这允许你在 expect
脚本中使用这些参数来执行特定的操作或配置脚本行为。
要运行带有参数的 expect
脚本,你可以使用以下命令:
expect your_script.exp 参数1 参数2
在这个命令中,your_script.exp
是你的 expect
脚本的文件名,后面的参数1、参数2 等是你要传递给脚本的参数。脚本可以根据需要接受任意数量的参数,只需使用 lindex
函数获取它们并将其存储在变量中即可。
例如,如果你的 expect
脚本需要用户名和密码作为参数,你可以这样使用:
#!/usr/bin/expect
set username [lindex $argv 0]
set password [lindex $argv 1]
# 使用用户名和密码进行登录操作
然后在命令行中执行脚本:
expect your_script.exp my_username my_password
这样,你可以将参数传递给 expect
脚本,以根据需要执行不同的操作。
示例
expect捕获要精确捕获
嵌入执行模式
实现一个免交互挂载
#!/bin/bash
dev=$1
num=$2
ml=$3
/usr/bin/expect <<EOF
set timeout 5
sleep 3
spawn fdisk $dev
expect {
"命令" {send "n\r";exp_continue}
"Select" {send "p\r";exp_continue}
"分区号" {send "$num\r";exp_continue}
"起始" {send "\r"}
}
expect "Last" {send "+5G\r"}
expect "命令(输入 m 获取帮助):" {send "w\r"}
expect eof
EOF
partprobe
mkfs.xfs -f ${dev}${num}
mount ${dev}${num} ${ml}