如何在perl脚本退出之前运行一段代码

时间:2010-06-20 07:22:06

标签: perl

在我的脚本中,我需要从磁盘文件加载一些信息,并且在脚本运行期间可能会更改信息。要保持文件在磁盘中的一致性,并且它在内存副本中我需要 只要在内存中更改信息或定期写入信息,就将信息写回磁盘 返回磁盘或在脚本退出时将其写回,这是首选的,因为它将节省大量IO时间并使脚本响应。

所以就像标题一样,我的问题是perl是否有一些能满足我需求的机制?

3 个答案:

答案 0 :(得分:27)

我认为您正在寻找END block

END {
    # cleanup
}
  

END代码块尽可能晚地执行,也就是说,在perl完成程序运行之后并且在退出解释器之前,即使它是由于die()函数退出。 (但是如果它通过exec变成另一个程序,或者被信号吹出水面 - 你必须自己陷阱(如果可以的话)。)你可能在文件中有多个END块 - 它们会以与定义相反的顺序执行;那就是:后进先出(LIFO)。使用-c开关运行perl时,或者编译失败时,不会执行END块。

答案 1 :(得分:9)

根据您的需求,有两种不同的方法可以做到这一点。

  • 解释器关闭时执行END块。有关详细信息,请参阅上一个答案:)
  • 当您的对象超出范围时执行的DESTROY块/子。也就是说,如果您想将逻辑嵌入到模块或类中,则可以使用DESTROY

看一下下面的例子(这是一个有效的例子,但是省略了错误检查等一些细节):

#!/usr/bin/env perl

package File::Persistent;

use strict;
use warnings;
use File::Slurp;

sub new {
    my ($class, $opt) = @_;

    $opt ||= {};

    my $filename = $opt->{filename} || "./tmpfile";
    my $self = {
        _filename => $filename,
        _content => "",
    };

    # Read in existing content
    if (-s $filename) {
        $self->{_content} = File::Slurp::read_file($filename);
    }

    bless $self, $class;
}

sub filename {
    my ($self) = @_;
    return $self->{_filename};
}

sub write {
    my ($self, @lines) = @_;
    $self->{_content} .= join("\n", @lines);
    return;
}

sub DESTROY {
    my ($self) = @_;
    open my $file_handle, '>', $self->filename
        or die "Couldn't save persistent storage: $!";
    print $file_handle $self->{_content};
    close $file_handle;
}

# Your script starts here...
package main;

my $file = File::Persistent->new();

$file->write("Some content\n");

# Time passes...
$file->write("Something else\n");

# Time passes...
$file->write("I should be done now\n");

# File will be written to only here..

答案 2 :(得分:1)

要处理Control-C,您需要处理信号(不触发END块)。下一步可以完成:

$SIG{INT}  = \&signal_handler;
$SIG{TERM} = \&signal_handler;

sub signal_handler {
    #implement here pre exit logic
    die "\n";
}