【问题标题】:Terminate tcpdump in script and continue executing next command在脚本中终止 tcpdump 并继续执行下一个命令
【发布时间】:2017-03-21 20:53:11
【问题描述】:

我正在尝试创建一个我拥有的脚本:

tcpdump (options) | fgrep (options) > file

使用 CTRL+C 终止 tcpdump 后,我希望执行这些命令:

sed (options) file | awk (options)
wait
rm file

第一部分已经完成,但是在我按下 CTRL+C 后,我被抛出到提示符。我尝试了等待,使用陷阱 SIGINT,同样的问题。

现在要弄清楚这一点:为什么不简单地通过管道传输所有内容而不将中间未过滤的输出转储到临时文件?好吧,我试过了,但似乎信息在我的屏幕输出中丢失了(服务器繁忙,不知道),我发现打破这样的命令可以让我获得完整的输出。

更新: 根据我在下面得到的答案,我尝试这样做,这似乎是使其工作的最安全方法:

function1 ()
{
tcpdump (options) | fgrep (options) > file
trap "function2" SIGINT SIGTERM
}

function2 ()
{
sed (options) file | awk (options)
wait
rm -i file
}

它不起作用。生成了“文件”,但 sed | 似乎没有读取和过滤其内容在我执行 CTRL+C 之后的 awk 语法,它甚至没有被 rm 命令删除,所以这进一步证明了辅助的被困函数没有被执行。我不明白这种行为,我做错了吗?

更新 2: 我可以让它正常工作的唯一方法是这样的:

set -m

tcpdump (options) | fgrep (options) > filename &

trap "kill -9 $!" SIGINT

sed (options) filename | mawk (options)

\rm filename

但我无法通过杀死后台进程来抑制输出,尝试了我能找到的所有解决方案: Running bash commands in the background without printing job and process ids - 这个让我的陷阱不起作用; With Bash Scripting, how can I suppress all output from a command? - 这里的所有变体都不起作用,无论我做什么,我仍然得到输出。尝试定义 $!使用另一个变量,尝试了 /dev/null 的所有变体,尝试将其放在陷阱命令中,没有用。

【问题讨论】:

    标签: bash tcpdump terminate bash-trap


    【解决方案1】:

    在后台启动tcpdump 命令并在固定时间后终止它对您有用吗?例如。运行

    (tcpdump (options) | fgrep (options) > file) & 
    

    然后获取进程的pid,等待一段时间,

    pid=$! 
    sleep 60
    

    最后杀死命令并解析输出

    kill -9 $pid
    sed (options) file | awk (options)
    rm file
    

    更新

    如果你真的想让Ctrl-P 停止tcpdumptrap 就是你要走的路。但是,在执行了被困命令之后,您将始终以 shell 结束!所以你描述的行为实际上是trap应该做的。

    因此您可以将trap 命令编写为

    trap "{ sed (options) file | awk (options); rm file; }" SIGINT SIGTERM
    

    它应该对中断执行所有后处理。如果您拥有的不仅仅是这些简单的命令,那么将所有后处理命令放在一个新的脚本或函数中可能更有意义,例如

    exec_on_interrupt() {
      sed (options) file | awk (options)
      rm file
      # other stuff...
    }
    
    trap "exec_on_interrupt" SIGINT SIGTERM
    

    【讨论】:

    • 不幸的是,无法为我想使用它指定定义的时间量。终止 tcpdump 必须由用户通过 CTRL+C 完成。
    • 在后台运行并不是一个坏主意......也许你可以按照@Michael 的建议做,让你的 bash 脚本在你准备好杀死它时等待一些用户输入(“按 q当您希望 tcpdump 停止时...”,然后坐在那里等待)。捕获这样的输入似乎比强制 CTRL+C 表示“杀死 tcpdump 进程而不是这个脚本”更容易。
    • 我更新了我的问题,不幸的是,提供的解决方案在我的机器上似乎没有按预期工作,我不明白为什么。
    • 我终于通过使用第一个建议的解决方案让它工作并定义了一个键,当按下该键时将为 PID 执行 kill -9 命令。我仍然希望使用 CTRL+C 来终止 tcpdump。
    猜你喜欢
    • 1970-01-01
    • 2015-04-24
    • 2021-04-06
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多