作成後に複数のスクリプトから読み取る一時ファイルを作成したいのですが、最後のスクリプトがこの一時ファイルの読み取りを完了した時点を監視して、毎回削除(他のスクリプトの場合もあります)する簡単な方法はありません。 )。どのプログラムでも読み取らずに特定の時間間隔が経過すると、ファイルを自動的に削除するコマンドラインツールを使用してこの問題を解決する標準的な方法があるかどうか疑問に思います。これは可能ですか?それともこの問題を解決する唯一の方法は、最後のスクリプトがファイルを削除するためにファイルの読み取りが完了した時期を知る方法を見つけることですか?
答え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
。解決策を知っている人がいる場合は、ここにコメントを自由に作成してください。 :)