在脚本中循环时不能停止

时间:2015-02-05 13:39:57

标签: perl timeout

我写过超级简单的脚本,通过我的日志文件旋转并无休止地拖尾。

我的问题是我无法 Ctrl + C 这个程序我需要 Ctrl + Z 并在之后杀死它。

我该如何解决这个问题? 我已经尝试过perl,但我有一个msg"闹钟"我想避免。 用perl我可以 Ctrl + C 就好了。

perl -e "alarm 10; exec @ARGV" "tail -15f $line | filter"

我的代码:

#!/bin/bash
    #
    while :
    do while read line
            do
                    charcount=$(ls $line | awk '{ print length; }')
                    printf '%0.s=' $(seq 1 $charcount)
                    echo -e "\n$line"
                    printf '%0.s=' $(seq 1 $charcount)
                    printf '\n'
                    timeout 10s tail -15f $line | filter
            done < <(ls /var/log/net/*.log)
    done

谢谢!

1 个答案:

答案 0 :(得分:1)

您提到的“闹钟”提醒是因为这是处理由SIGALRM函数生成的alarm信号的默认方式。

Ctrl-C不起作用的常见原因是因为发生了阻塞调用,因此发送的SIGINT信号不会被捕获和处理。我无法在你的代码中看到任何明显的因素。

在我看来,最明显的方法是 - 停止混合perl和bash,因为这种方式就是疯狂。

在Perl中使用File::Tail模块怎么样?这甚至有一个如何做你想要的事情的例子:

 #!/usr/bin/perl

use strict;
use warnings;

use File::Tail;

foreach (@ARGV) {
    push( @files, File::Tail->new( name => "$_", debug => $debug ) );
}
while (1) {
    ( $nfound, $timeleft, @pending ) =
        File::Tail::select( undef, undef, undef, $timeout, @files );
    unless ($nfound) {

        # timeout - do something else here, if you need to
    }
    else {
        foreach (@pending) {
            print $_->{"input"} . " ("
                . localtime(time) . ") "
                . $_->read;
        }
    }
}

这可能会让你在运行它时ctrl-c,但Perl允许你通过%SIG哈希更好地控制信号 - 允许你定义杀手信号的自定义处理程序 - 比如来自SIGALRM的{​​{1}}和来自alarm的{​​{1}}。