我如何复制立即被删除的文件

我如何复制立即被删除的文件

我有一个脚本,该脚本会创建一个转储/path/of/directory并立即将其删除。我想在删除之前复制该转储。

我试过;

dump=$(ls -a | grep -E "^[0-9]+$")
cp $dump fulldump

但我只拿到了一半的剧本,而不是完整的。

答案1

您可以使用 chattr 来防止文件删除(同时允许文件创建和修改),以及其他方便的权限

对于目录:

sudo chattr -R +a /TEMP/

或者如果只是(现有)文件:

sudo chattr +a /TEMP/youCantDeleteMe.txt

要恢复权限,请-a使用+a

$ mkdir Documents/TEMP && cd $_
$ echo can edit > youCantDeleteMe.txt 

$ sudo chattr -R +a ../TEMP/

$ echo after plusA on file>> youCantDeleteMe.txt 
$ cat youCantDeleteMe.txt 
can edit
after plusA on file

$ sudo rm youCantDeleteMe.txt 
rm: cannot remove 'youCantDeleteMe.txt': Operation not permitted

$ ls -lA
-rw-rw-r-- 1 v v   25 Sep  5 05:59 youCantDeleteMe.txt
$ echo . > youCantDeleteMe.txt 
bash: youCantDeleteMe.txt: Operation not permitted

$ touch somebody
$ ls -lA
-rw-rw-r-- 1 v v  0 Sep  5 06:04 somebody
-rw-rw-r-- 1 v v 25 Sep  5 05:59 youCantDeleteMe.txt

$ sudo rm somebody 
rm: cannot remove 'somebody': Operation not permitted

$ sudo chattr +a ./undel.txt
chattr: No such file or directory while trying to stat ./undel.txt

稍后删除文件

$ sudo chattr -R -a ../TEMP/
$ ls -lA
drwxrwxr-x 2 v v 4096 Sep  5 06:17 .
drwxr-xr-x 7 v v 4096 Sep  5 05:57 ..
-rw-rw-r-- 1 v v    0 Sep  5 06:04 somebody
-rw-rw-r-- 1 v v   25 Sep  5 05:59 youCantDeleteMe.txt

$ rm -rf ./*
$ ls -la
drwxrwxr-x 2 v v 4096 Sep  5 06:17 .
drwxr-xr-x 7 v v 4096 Sep  5 05:57 ..
 

答案2

恭喜,你似乎已经创建了一个竞争条件

  • 两个过程赛车对同一个文件执行操作。

  • 一般来说,竞争条件被认为是一个错误,其原因正是您遇到的——结果是不可预测的。

有多种方法可以修复竞争条件(信号量、锁文件、延迟等),其中一些可能涉及相当大量的编码。

但是,就您的具体情况而言,您询问的是脚本。幸运的是,您可以编辑脚本。最简单的解决方案是编辑脚本以将转储放置在您喜欢的位置。

答案3

strace实用程序通常用于显示进程发出的系统调用,但也可以拦截它们。

尝试:

strace -f -e inject=unlink,unlinkat:retval=0 /the/script script-args...

然后,每次该进程或其子进程调用unlinkunlinkat系统调用(这是删除文件的正常方式)时,strace都会拦截它并使其返回 0,表示成功,但实际上并不执行任何操作。

跟踪所有系统调用会产生大量输出。您可以添加-e trace=unlink,unlinkat以仅显示这些调用,或-o logfile将整个输出发送到文件(可能/dev/null)。确保这些参数/the/script位于命令行之前。

注意这将阻止脚本删除任何根本无法跟踪文件;希望这样没问题。有一个-P选项strace可以限制跟踪访问给定文件的调用,但我无法在简单测试中让它正常工作。

还有其他变体也是可能的:例如,您可以让unlink/unlinkat系统调用失败并显示错误代码,或者让它们向进程发送 SIGSTOP,以便您可以在继续之前进行检查。有关其所有功能的详细信息,请参阅 strace 手册页。

答案4

根据转储打开和写入的速度,您可能能够创建一个难的在写入时链接到它。此硬链接将确保在使用其原始名称删除文件时不会释放数据空间。例如:

your-script &
ln /path/of/directory/dumpfile /some/other/path/on/the/same/filesystem
wait   #  wait until your-script exits
do-something-with /some/other/path/on/the/same/filesystem

相关内容