Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 当程序意外停止时,如何自动删除使用File::Temp创建的文件?_Perl - Fatal编程技术网

Perl 当程序意外停止时,如何自动删除使用File::Temp创建的文件?

Perl 当程序意外停止时,如何自动删除使用File::Temp创建的文件?,perl,Perl,我正在使用File::temp创建临时文件。程序正常退出时,我的临时文件会自动删除。当我的程序用ctrl+c停止时,我也希望发生同样的情况。事实并非如此 这里有一个简单的程序来演示我的问题 期望的行为是这样的。我怎样才能做到呢?我在Linux上 关闭文件句柄时不会删除临时文件(确定) 程序正常退出时删除临时文件(确定) 当程序以ctrl+c(不工作)退出时,临时文件被删除 编辑1 我测试了tempfile的行为。它似乎证实了Linux支持我正在寻找的东西(将文件标记为临时文件/取消链接打开

我正在使用File::temp创建临时文件。程序正常退出时,我的临时文件会自动删除。当我的程序用ctrl+c停止时,我也希望发生同样的情况。事实并非如此

这里有一个简单的程序来演示我的问题

期望的行为是这样的。我怎样才能做到呢?我在Linux上

  • 关闭文件句柄时不会删除临时文件(确定)
  • 程序正常退出时删除临时文件(确定)
  • 当程序以ctrl+c(不工作)退出时,临时文件被删除

编辑1

我测试了tempfile的行为。它似乎证实了Linux支持我正在寻找的东西(将文件标记为临时文件/取消链接打开文件)。我似乎有一个理想化的File::Temp

# program will die because os deletes tmpfile after close
my $fh = tempfile;
close $fh;
stat $fh || die;
readline STDIN;

你真的需要文件名吗?如果没有,请使用

my $fh = tempfile();

您是否尝试将清理代码放入和结束块?

要使控制键盘中断运行您的
结束块,您需要添加一个信号处理程序。比较以下各项的行为:

perl -E 'END{say "END"};<STDIN>'

我看了源代码。我甚至检查了最新的版本(在撰写本文时为0.22)。我想对File::Temp执行的操作是设计不允许的

创建对象时,将使用数组上下文创建临时文件,如下所示:

sub new {
  ...
  # Open the file and retain file handle and file name
  my ($fh, $path) = tempfile( @template, %args );
在数组上下文中创建tempfile意味着该文件永远不会自动取消链接(即使在支持它的平台上)。该文件被标记为延迟取消链接,这意味着当程序正常退出时,它将被删除

sub tempfile { 
  ...
  _deferred_unlink($fh, $path, 0) if $options{"UNLINK"};

  # Return
  if (wantarray()) {

    if ($options{'OPEN'}) {
      return ($fh, $path);
    } else {
      return (undef, $path);
    }

  } else {

    # Unlink the file. It is up to unlink0 to decide what to do with
    # this (whether to unlink now or to defer until later)
    unlink0($fh, $path) or croak "Error unlinking file $path using unlink0";

    # Return just the filehandle.
    return $fh;
  }
如果我想继续使用File::Temp,我需要设置一个信号处理程序,以便在程序中止时强制清理。如果需要考虑可移植性,我还应该设置一个sig处理程序,因为在某些平台上提供的只是延迟取消链接。很好的一点是,File::Temp创建了一个结束块,因此根本没有什么要做的:

use sigtrap qw(die normal-signals error-signals);
如果不考虑可移植性,并且平台支持自动文件清理,那么使用tempfile是可以的(在标量上下文中)

以下评论很好地解释了该设计背后的基本原理:

当我们打开文件时,我们必须指出临时性一般 我们只需要一个真正的临时文件,如果我们只返回 filehandle-如果用户想要他们可能不想要的文件名 一旦他们关闭该文件,该文件将立即消失(这可能很重要) 如果他们希望子进程使用该文件)


我在寻找类似的东西,我想我找到了一个相当好的小解决方案

从根本上讲,这并不是什么新鲜事,但可能比安装自己的
END
块等更简单:

use sigtrap qw(die INT); # ensures DESTROY methods are run on Ctrl-C

my $temp = File::Temp->new(UNLINK => 1);
my $filename = $temp->filename;
# When $temp goes out of scope, the file will be
# deleted, and $filename will be invalid.
# Further, a Ctrl-C will cause $temp->DESTROY to be invoked,
# which will also delete the temp file.

@ikegami:他在LinuxI上,我并不绝对需要它,但它非常适合我当前的实现。稍后,我在临时文件中重定向了许多系统命令。使用文件名似乎比使用句柄更容易。是否确实在使用ctrl+c中止脚本时调用结束块?我做了一个快速测试,发现它不是:perl-e'END{print“END\n”}readline STDIN'我对一个尽可能透明的解决方案感兴趣,特别是我的操作系统支持自动清理临时文件。信号处理程序是最可移植的解决方案,它允许我不更改程序。
sub tempfile { 
  ...
  _deferred_unlink($fh, $path, 0) if $options{"UNLINK"};

  # Return
  if (wantarray()) {

    if ($options{'OPEN'}) {
      return ($fh, $path);
    } else {
      return (undef, $path);
    }

  } else {

    # Unlink the file. It is up to unlink0 to decide what to do with
    # this (whether to unlink now or to defer until later)
    unlink0($fh, $path) or croak "Error unlinking file $path using unlink0";

    # Return just the filehandle.
    return $fh;
  }
use sigtrap qw(die normal-signals error-signals);
use sigtrap qw(die INT); # ensures DESTROY methods are run on Ctrl-C

my $temp = File::Temp->new(UNLINK => 1);
my $filename = $temp->filename;
# When $temp goes out of scope, the file will be
# deleted, and $filename will be invalid.
# Further, a Ctrl-C will cause $temp->DESTROY to be invoked,
# which will also delete the temp file.