1. ホーム
  2. linux

[解決済み] ファイル名に"/"を使用することは可能ですか?

2022-06-16 18:04:02

質問

絶対にやってはいけないことだとは思うのですが、Linux でファイル名の中で通常ディレクトリを区切るスラッシュ文字を使用する方法はありますか?

どのように解決するのですか?

答えは、ファイルシステムにバグがない限り、無理です。その理由は次のとおりです。

で定義されたファイル名を変更するためのシステムコールがあります。 fs/namei.c と呼ばれる renameat :

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                int, newdfd, const char __user *, newname)

システムコールが呼び出されると、パスのルックアップを行います ( do_path_lookup ) を行います。これをトレースし続けると link_path_walk にたどり着き、これを持っています。

static int link_path_walk(const char *name, struct nameidata *nd)
{
       struct path next;
       int err;
       unsigned int lookup_flags = nd->flags;

       while (*name=='/')
              name++;
       if (!*name)
              return 0;
...

このコードはどんなファイルシステムにも適用されます。これは何を意味するのでしょうか?それは、もしあなたがパラメータを渡すときに実際の '/' 文字をファイル名としてパラメータに渡そうとした場合、 従来の方法では思い通りにならないことを意味します。この文字をエスケープする方法がないのです。ファイルシステムがこれをサポートしている場合は、以下のいずれかの理由によるものです。

  • ユニコード文字または に見えるもの のように見えるがスラッシュではないものを使用する。
  • バグがあります。

さらに、もしあなたが した を実行し、ファイル名にスラッシュ文字を追加するためにバイトを編集すると、悪いことが起こります。なぜなら、このファイルを名前で参照することは決してできないからです :( なぜなら、参照するときはいつでも、Linux は存在しないディレクトリを参照していると仮定するからです。rm *」というテクニックを使っても、bashは単にそれをファイル名に展開するだけなので、うまくいきません。でも rm -rf でさえうまくいかないでしょう。なぜなら、単純な strace はボンネットの下で物事がどのように進行しているかを明らかにするからです。

$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0)               = 0
unlinkat(3, "out", 0)                   = 0
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(3)                                = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...

これらの unlinkat の呼び出しは、ファイル名で参照する必要があるため失敗することに注意してください。