我想创建一个临时文件,该文件在创建后将被多个脚本读取,但是我没有一种简单的方法来监视最后一个脚本何时完成读取此临时文件以将其删除(它可能是不同的脚本)每一次)。我想知道是否有一种使用命令行工具解决此问题的标准方法,当该文件经过特定的时间间隔而不被任何程序读取时,该工具会自动删除该文件,这可能吗?或者解决这个问题的唯一方法是找出一种方法来知道最后一个脚本何时完成读取该文件以将其删除?
答案1
使用 inotifywait,您可以将以下内容添加到访问该文件的脚本中。
if ! inotifywait $FILE -t $SECONDS >/dev/null 2>&1
then rm $FILE
fi &
该脚本将生成一个进程,等待某些内容访问 $FILE。
如果有什么事情发生,它什么都不做并退出。
如果在 $SECONDS 之后达到超时,它将删除该文件
或者使用单独的脚本,在创建文件时运行该脚本
while inotifywait $FILE -t $SECONDS >/dev/null 2>&1
do sleep 1
done
rm $FILE
每当文件被访问时它就会循环,
如果在超时时间内没有任何内容访问它,它就会中断并删除该文件。
答案2
基于太宇的答案使用inotifywait
我已经创建了一个node.js
解决方案来解决这个问题...它需要的细节比我询问时预期的更多。抱歉,如果这不是发布 Node.js 代码的正确位置,但该语言的异步特性使事情对我来说变得更简单......我的解决方案如下:
const fs = require('fs');
const spawn = require("child_process").spawn;
const file='/home/user/hugefile.csv';
let counter = 0; // counter used for identifying how many times the file was opened and closed by a different program
const child = spawn('/bin/bash', [ '-c', `inotifywait --format=%e -q -m -e access,close ${file}` ])
child.stdout.on('data', (data) => {
let line = data.toString().split('\n').filter(item => item); // get events inside a javascript array and filter empty values
// loop through the inotify events
line.forEach(function(event) {
if ( event === "ACCESS" )
counter++;
else if ( event === "CLOSE_NOWRITE,CLOSE" )
counter--;
// asynchronous function that checks the value of counter after 10 seconds
async function timer() {
await sleep(10000);
console.log(counter);
if ( counter === 0 ){
fs.unlinkSync(file); // erase file
console.log("tmpfile erased!")
process.exit();
}
}
timer();
});
});
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
基本上,我用作inotifywait
解决问题的基础...我只需要在创建临时文件后执行此脚本,它会在所有其他程序完成读取文件后(10 秒后)删除该文件。
OBS:我试图解决这个问题的问题bash
是,当我让一个函数作为一个进程运行时,&
我失去了对该函数内全局变量的新值的控制。所以我无法counter
使用与我使用过的相同逻辑来获取状态node.js
...如果有人知道解决方法,请随时在此处写下评论。 :)