Linux笔记之expect和bash脚本监听输出并在匹配到指定字符串时发送中断信号
code review!
文章目录
- Linux笔记之expect和bash脚本监听输出并在匹配到指定字符串时发送中断信号
- 1.expect
- 2.bash
1.expect
在Expect脚本中,你可以使用expect
来监听程序输出,并在输出匹配特定的模式时发送一个中断信号(如Control-C)。以下是一个使用expect
脚本的基本示例,用于监听特定的输出并发送中断信号:
例1
#!/usr/bin/expect
# 启动你的进程
spawn your_process
# 设置一个超时时间,防止永远等待
set timeout 30
# 监听输出,直到匹配到 "pattern_to_match" 文本
expect "pattern_to_match"
# 模式匹配后发送 Control-C 中断信号
send "\003"
# 继续处理其他事情或结束脚本
expect eof
your_process
是你想要启动和控制的程序。pattern_to_match
是你期待输出中出现的文本模式。
例2
#!/usr/bin/expect -f
# 设定无超时限制
set timeout -1
# 启动你的进程
spawn ./your_program
# 使用expect命令匹配输出
expect {
# 当匹配到"特定文本"时,执行大括号内的代码
"特定文本" {
# 发送Control-C信号
send "\003"
# 可以选择发送其他命令或打印信息
send_user "已发送中断信号(Control-C)。\n"
}
# 处理可能出现的其他情况
"其他模式1" {
# 对于其他模式1, 执行对应操作
# ...
}
"其他模式2" {
# 对于其他模式2, 执行对应操作
# ...
}
# 如果发生超时,处理超时情况
timeout {
send_user "操作超时。\n"
exit 1
}
}
# 处理进程结束
expect eof
在这个脚本中:
spawn ./your_program
启动你想要监控的程序。你需要将./your_program
替换为实际的程序命令。expect
命令用于监听程序的输出。"特定文本"
应该被替换为你希望匹配的输出文本。- 当输出匹配到
"特定文本"
时,send "\003"
命令发送Control-C信号,这通常会导致大多数命令行程序终止。 send_user "已发送中断信号(Control-C)。\n"
命令是可选的,用于向用户反馈信息。"其他模式1"
和"其他模式2"
代表了其他可能匹配的输出模式,你可以根据需要添加或修改这些模式及其对应的动作。timeout
处理程序如果没有在预定时间内给出任何匹配输出时的情况。
expect命令可以匹配输出中的部分字符串,不需要整行或完整字符串匹配!
expect
命令可以匹配输出中的部分字符串。expect
是一个用于自动化交互式应用程序的命令行工具,它使用 Tcl 语言的脚本。其核心功能是等待特定的字符串出现在程序的输出中,然后根据脚本中定义的模式进行响应。
在 expect
脚本中,可以使用 expect
命令来等待特定的文本模式出现。这些模式可以是完整行也可以只是行中的某个子串。expect
使用了类似于正则表达式的模式匹配方式来定位输出中的文本。
以下是一个简单的 expect
脚本示例,该脚本等待部分字符串的出现:
#!/usr/bin/expect
# 启动某个交互式命令
spawn some_command
# 等待输出中出现 "password:" 子字符串
expect "password:"
# 当看到 "password:" 时发送密码
send "my_password\r"
# 继续处理...
在上面的脚本中,expect "password:"
表示脚本会等待输出中出现 “password:” 这个子字符串。一旦匹配到,expect
就会执行下一条命令 send
来发送密码。
expect
还可以使用更复杂的正则表达式来匹配更灵活的模式。例如:
expect {
"username:" {
send "my_username\r"
exp_continue
}
"password:" {
send "my_password\r"
}
timeout {
send_user "Connection timed out\n"
exit
}
}
在这个示例中,使用了 expect
的复合命令语法来匹配多个可能的输出,包括 “username:” 和 “password:”,并且也处理了超时情况。
使用 expect
时,记得模式匹配默认是全局的,它会在整个输出中搜索你的字符串,而不需要匹配整行。如果需要更精确的控制,可以使用正则表达式来指定匹配的条件。
2.bash
在Bash脚本中,你可以使用 trap
命令来捕捉信号并执行一个命令序列。不过,Bash本身并不是用来做交互式的自动化的最佳工具,因为它没有像Expect那样的模式匹配功能。然而,你可以通过结合使用Bash脚本和工具如 grep
、sed
或 awk
来监控进程输出,并使用 kill
命令发送信号。
以下是一个简单的例子,这个例子中,我们使用了一个循环来持续读取某个进程的输出,并在发现特定模式时发送SIGINT信号:
#!/bin/bash
# 启动你的进程并记录它的PID
your_process &
PID=$!
# 使用tail -f来获取进程的实时输出
tail -f your_process.log | \
while read LINE
do
echo "$LINE"
# 检查行内容是否包含特定模式
if [[ "$LINE" == *pattern_to_match* ]]; then
# 发送SIGINT (通常等同于Control-C)
kill -SIGINT $PID
break
fi
done
# 等待进程结束
wait $PID
在这个脚本中,your_process
应该被替换为你想要启动的命令,而 your_process.log
应该是该进程的输出文件。pattern_to_match
应该是你想要匹配的文本模式。
请注意,这些示例可能需要根据你的实际需求进行调整。使用Bash来监听和处理实时输出可能会比较复杂,尤其是如果输出速率非常快或者模式比较复杂的时候。Expect脚本天生就是为了处理这类交互设计的,所以通常会是一个更好的选择。