他のプログラムから読み取らずに一定時間が経過すると自動的に削除される一時ファイルを作成できますか?

他のプログラムから読み取らずに一定時間が経過すると自動的に削除される一時ファイルを作成できますか?

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

答え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。解決策を知っている人がいる場合は、ここにコメントを自由に作成してください。 :)

関連情報