Linux笔记之expect和bash脚本监听输出并在匹配到指定字符串时发送中断信号

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

在这个脚本中:

  1. spawn ./your_program 启动你想要监控的程序。你需要将 ./your_program 替换为实际的程序命令。
  2. expect 命令用于监听程序的输出。
  3. "特定文本" 应该被替换为你希望匹配的输出文本。
  4. 当输出匹配到 "特定文本" 时,send "\003" 命令发送Control-C信号,这通常会导致大多数命令行程序终止。
  5. send_user "已发送中断信号(Control-C)。\n" 命令是可选的,用于向用户反馈信息。
  6. "其他模式1""其他模式2" 代表了其他可能匹配的输出模式,你可以根据需要添加或修改这些模式及其对应的动作。
  7. 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脚本和工具如 grepsedawk 来监控进程输出,并使用 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脚本天生就是为了处理这类交互设计的,所以通常会是一个更好的选择。

Linux笔记之expect和bash脚本监听输出并在匹配到指定字符串时发送中断信号_第1张图片

你可能感兴趣的:(Linux笔记,linux,笔记,bash)