Perl:使用文件打开撤销unlink操作

5

unlink 不会删除已打开的文件,它只是删除文件名和链接。那么,unlink 可以被撤销吗?

open(my $fh, ">", undef) || die;
print $fh "foo";
# This does not work
link($fh,"/tmp/bar") || die;

可以将指向未链接文件的打开文件句柄链接到文件吗?
2个回答

3
如果可行的话,您可以将打开模式('>')更改为读/写模式。然后,当您需要恢复文件时,您可以使用文件句柄将其打印到新打开的文件中,即使需要使用相同的名称。
open my $fh, '+>', $file;
say $fh "line 1";
unlink $file;
say $fh "more lines";

seek $fh, 0, 0;
open my $fh_rec, '>', $file   or die "Can't open $file (again): $!";
print $fh_rec $_ while <$fh>;

这并不是正好被要求的方式,但它可以恢复文件内容并访问它。进一步对$fh打印会使新的$file不同步,因此可以在写入完成后执行(以恢复文件),或将打印切换到$fh_rec(然后也关闭$fh)。
另一种恢复文件的方法是使用操作系统,如果它使用/proc并公开文件句柄,则可以从/proc/PID/fd/N中复制数据。要识别N,可以扫描fd/中的所有链接(很少)以及ls -l,因为删除的文件应该在其名称后面带有(已删除)
此外,lsof -p PID列出给定进程的所有打开文件描述符。对于已删除的文件,它们随后有(已删除)。(用lsof +L1 -p PID只输出已删除的条目,仍然相当多。) 从此输出中,我们可以读取文件描述符,然后从/proc/PID/fd/N复制数据。这样我们还可以获取i节点号,也可以用于恢复文件。

0

我完全同意,这方面没有设施,也没有可以“通常”使用的程序。我很好奇是否我遗漏了什么,你为什么说“从打开的文件句柄复制内容可能有效”(强调是我的)?只要文件以rw模式打开,我发布的内容就有效(或者说——怎么可能无效呢?)。当然,它不会还原原始链接。 - zdim
如果重新链接的整个原因是为了避免重新读取文件(这正是我的情况),那么复制内容是行不通的。 - Ole Tange
啊,好的。我没有意识到那是目的。 - zdim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接