ファイルが削除されたときにスクリプトを実行するにはどうすればよいですか?


1

アプリケーションが生成する実際の生データを含むはるかに大きな.tifファイルのリストを含むXML 'jobfiles'の形式でデータを保存するアプリケーションがあります。通常、アプリケーションのユーザーはXMLジョブファイルの場所のみを気にします:これが移動または名前変更された場合、それらへのフルパス(多くの場合リモートドライブ上にあるため)が.tifファイルのリストは有効のままです目的専用)は、ユーザーに対して透過的な方法でファイル内に記録されます。このように処理することにより、ジョブファイルは数十ギガバイトに膨らむのではなく、小さく保つことができます。

ただし、ユーザーがOSから(Windowsの場合はcmdウィンドウまたはWindowsエクスプローラーから、Linuxの場合はbashシェルまたはNautilusから)ジョブファイルを削除することを決定した場合は、ジョブファイルとその画像データが切断されます。ジョブファイルに関連付けられた画像ファイルは「孤立」し、アプリケーションからアクセスできなくなりますが、それでもドライブのスペースを占有します。

XMLファイルを解析し、その中にリストされている画像ファイルを識別し、それらを削除するシェルスクリプトを書くのは簡単です。ユーザーがファイルを削除するたびにこのシェルスクリプトが自動的に実行れるようにすると、問題が一気に解決します。ただし、WindowsまたはLinuxでファイルが削除されるたびにスクリプトが実行されるようにOSを構成する方法はまったくわかりません。

これを行う方法はありますか?


1
ウォッチャーを使用してイベントと応答のアプローチを実装できますが、動作が非常に異なるため、WindowsとLinuxの両方に個別のバージョンを作成する必要があります。窓のために私は、.NETアプリケーションを記述しますが、このPowerShellスクリプトも同様に行う必要があります。gallery.technet.microsoft.com/scriptcenter/...
フランク・トーマス

Linuxでは、inotifywaitを使用します
John1024

ありがとうございました; ただし、.NetのFileSystemWatcherクラスとLinuxのinotify APIの両方を確認できる限り、ファイルが削除された後に信号が送信されます。 (ごみ箱から一時的に回復できない限り)。私が見つけたいと思っていたのは、ユーザーが削除を要求した後、実際の削除が行われる前にスクリプトを呼び出す方法です(C ++デストラクタのようなもの)、削除されるファイルの内容まだ読むことができます。
Eos Pengwern

そのためには、Windows APIをフックする必要があります。実際にその可能性は確かではありませんが、標準のAPIの動作を中断したいので、フックが提供されない限り、それを実行するのは非常に困難です。
フランクトーマス

回答:


0

inotifywaitと呼ばれるコメントで言及されているようにの Windowsポートがありますinotify-win

ダウンロード:

https://github.com/thekid/inotify-win/archive/master.zip

コンパイル:

%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:inotifywait.exe src\*.cs

使用法:

$ inotifywait.exe
Usage: inotifywait [options] path [...]

Options:
-r/--recursive:  Recursively watch all files and subdirectories inside path
-m/--monitor:    Keep running until killed (e.g. via Ctrl+C)
-q/--quiet:      Do not output information about actions
-e/--event list: Events (create, modify, delete, move) to watch, 
                 comma-separated. Default: all
--format format: Format string for output.
--exclude:       Do not process any events whose filename matches the specified regex
--excludei:      Ditto, case-insensitive

Formats:
%e             : Event name
%f             : File name
%w             : Path name
%T             : Current date and time

編集:

悪意のあるアクションを回避したい場合、解決策はicaclsNTFSファイルシステムにあります。

ファイルを削除から保護するには:

icacls file.ext /deny Everyone:(DE)
rem To reset
icacls file.ext /reset

コンテンツを使用してフォルダーを保護するには:

icacls folder /deny Everyone:(OI)(CI)(DE,DC)
rem To reset
icacls folder /reset

*S-1-1-0Everyone言語に依存する代わりに%USERNAME%、現在のユーザーに対しても。


ありがとう、しかし元の質問の下で私のコメントを見てください。
Eos Pengwern

0

Linuxでは、次のような単純なbashスクリプトを使用できます。

#!/bin/bash

# Run code before and after prompting a user to delete a file

my_rm=/bin/rm
file1=$1

# Put the code you want to run pre-deletion here:
echo Running code before deleting ${file1}.

# Delete the file.
read -p "Are you sure you want to delete ${file1} (y/N): "  decision
if [ "$decision" == "Y" ] || [ "$decision" == "y" ]; then
        echo Deleting ${file1}...
        $my_rm $file1
        # Put the code you want to run post-deletion here:
        echo Running code after deleting ${file1}.
else
        echo No file deleted.
fi

# Put any cleanup code here:
echo Running cleanup code whether or not ${file1} was deleted.

exit

スクリプトmy-delete.shを呼び出すと仮定すると、それを実行可能にし、

chmod +x my-delete.sh

そして次のように実行します:

my-delete.sh jobfile.xml

これで、rmファイルの削除に使用する場合はrm、スクリプトのエイリアスを作成できます。

alias rm='/path/to/my-delete.sh'

前の行を〜/ .bashrcまたは〜/ .profileに追加するか、システムを適切な場所に追加して永続化します。

ジョブファイル以外のファイルに対して追加コードを実行したくない場合は、ファイル名またはファイルタイプのテストを追加し、それらのファイルに対してのみ追加コードを実行できます。次のスクリプトは、特別なコードを関数に挿入し、ファイル名をテストして、パターン「jobfile」が含まれているかどうかを確認します。

#!/bin/bash

# Run code before and after prompting a user to delete a file

my_rm=/bin/rm
file1=$1
pattern='jobfile'

function rm_jobfile () {
        # Put the code you want to run pre-deletion here:
        echo Running code before deleting ${file1}.

        # Delete the file.
        read -p "Are you sure you want to delete ${file1} (y/N): "  decision
        if [ "$decision" == "Y" ] || [ "$decision" == "y" ]; then
                echo Deleting ${file1}...
                $my_rm $file1
                # Put the code you want to run post-deletion here:
                echo Running code after deleting ${file1}.
        else
                echo No file deleted.
        fi

        # Put any cleanup code here:
        echo Running cleanup code whether or not ${file1} was deleted.
}

# If the file is a jobfile, run the function, otherwise just delete it.
if [[ $file1 =~ $pattern ]]; then
          rm_jobfile $file1
else
        $my_rm $file1
fi

exit

上記のエイリアスを作成したと仮定して、実行

rm jobfile1.xml

my-delete.shで機能コードを実行しますが、実行します

rm something.txt

しない。

Microsoft Windowsにはbash(およびLinuxカーネル)が含まれるようになったため、これもそこで実行されるはずですが、テストしていません。これからもpowershellスクリプトを適合させることができると確信しています。私はWindowsの男ではありません。お役に立てれば。


それは本当にすてきです。Linuxでどのように機能するかを見ることができますが、たとえば、rmからのディレクトリツリー全体の一部としてファイルが削除されている場合など、多くの余分なケースに拡張する必要がありますより高いレベル。また、通常のcmdウィンドウから操作する場合、Windowsにはこの種のエイリアスメカニズムがありません。ご想像のとおり、この質問をしてから4年近くが経過しているため、これを行う必要のない別のワークフローを開発しました。
Eos Pengwern
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.