特定の名前のフォルダが作成されないようにできますか?

特定の名前のフォルダが作成されないようにできますか?

私はLAMP Webアプリケーションを開発しており、どこかにshopサイトルートにあるフォルダを作成し続けるスケジュールされたプロセスがあります。これが発生するたびにアプリケーションの書き換え規則と競合が発生しますが、これは悪いことです。

問題のスクリプトが見つかるまでルートディレクトリにというshopフォルダが作成されないようにする方法はありますか?コンテンツが変更されないようにフォルダの権限を変更できることはわかっていますが、特定の名前のフォルダが作成されるのを防ぐ方法が見つかりませんでした。

答え1

ディレクトリを作成したユーザーには、親ディレクトリに書き込むための十分な権限があるため、そうすることはできません。

inotify代わりに、Linuxカーネルが提供する一連のシステムコールを利用して、ディレクトリがすでにmv作成されている場合(またはオプションで-ed)、指定されたディレクトリでディレクトリの作成(およびオプションで-ing)を監視できます。shopmvrm

この場合、必要なユーザースペースプログラムはinotifywait(一緒に提供されます。inotify-tools必要に応じて最初にインストールしてください)。


ディレクトリがディレクトリ内にshopあると仮定し、生成監視を/foo/bar設定し、生成直後にそれを見てみましょう。/foo/bar/shoprm

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/bar/foo/bar作成できるすべてのファイル/ディレクトリのディレクトリを監視します。つまり、すべてのcreateイベントを監視します。

  • 作成された場合は、そのファイルが()awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'という名前のディレクトリであることを確認し、そうである場合はそのディレクトリ()を確認します。shop/,ISDIR shop$/rmsystem("rm -r -- /foo/bar/shop")

ディレクトリから削除するには、ディレクトリへの書き込み権限を持つユーザーとしてコマンドを実行する必要があります/foo/barshop


-ingジョブを監視するには、mvイベント監視も追加しますmoved_to

inotifywait -qme create,moved_to /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'

ディレクトリの代わりに名前付きファイルを探す場合は、次の点に注意してくださいshop

inotifywait -qme create /foo/bar | \
                 awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'

inotifywait -qme create,moved_to /foo/bar | \
                 awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'

答え2

予防の質問に文字通り答えてくださいフォルダ生成する特定の名前です。

touch shop

同じ名前のファイルがある場合は、ディレクトリを作成できません。

mkdir: cannot create directory ‘shop’: File exists

答え3

mkdir以下を使ってシステムコールをハイジャックするのはどうですかLD_PRELOAD

$ ls
test.c
$ cat test.c 
#define _GNU_SOURCE

#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>

typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);

int mkdir(const char *path, mode_t mode) {
    if(!strcmp(path, "shop")) return 1;

    orig_mkdir_func_type orig_func;
    orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
    return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir test
$ LD_PRELOAD='./test.so' mkdir shop
mkdir: cannot create directory ‘shop’: No such file or directory
$ ls
test  test.c  test.so

このハンドラでは、このディレクトリを作成するプロセスのPIDを記録できます。

$ cat test.c 
#define _GNU_SOURCE

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>

typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);

int mkdir(const char *path, mode_t mode) {
    if(!strcmp(path, "shop")) {
        FILE* fp = fopen("/tmp/log.txt", "w");
        fprintf(fp, "PID of evil script: %d\n", (int)getpid());
        fclose(fp);
    }

    orig_mkdir_func_type orig_func;
    orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
    return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir shop
$ cat /tmp/log.txt 
PID of evil script: 8706

~/.bashrc使用するには、ルートディレクトリ(またはアプリケーションを実行している人)に配置する必要があります。

export LD_PRELOAD=/path/to/test.so

答え4

存在しないディレクトリの存在しない場所へのシンボリックリンクを作成します。ここにはいくつかの興味深い意味があります。

$ ln -s non-existent/foobar foo
$ ls -ln
total 0
lrwxrwxrwx 1 1000 1000 19 Okt  4 17:17 foo -> non-existent/foobar
$ mkdir foo
mkdir: cannot create directory ‘foo’: File exists
$ cat foo
cat: foo: No such file or directory
$ echo foo > foo
zsh: no such file or directory: foo
  1. EEXISTmkdir、リンク、その他のファイルは(ファイル付き)エラーのため失敗します。
  2. 読み取り、書き込み、または追加のためにパスを開こうとすると失敗しますENOENT(ファイルまたはディレクトリなし)。
  3. その場所でstat(2)(lstat(2)またはstat(1)ではない)を使用すると、ENOENTlstatも失敗します。もちろん、シンボリックリンクに関する情報が返されます。

ここで提案されている他のソリューションに比べて2つの利点があります。 (a) ディレクトリ生成を追跡するサービスを実行する必要はありません。 (b) ほとんどのコマンドに名前が存在しないようです。

試してみる必要があります。ただし、書き換え規則が何であれ、lstatや他の非参照コマンドを使用しないため、失敗する可能性があります。

関連情報