我有一个脚本,该脚本会创建一个转储/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...
然后,每次该进程或其子进程调用unlink
或unlinkat
系统调用(这是删除文件的正常方式)时,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