web-dev-qa-db-fra.com

Est-il possible d'utiliser "/" dans un nom de fichier?

Je sais que ce n’est pas quelque chose qui devrait être fait, mais existe-t-il un moyen d’utiliser le caractère barre oblique qui sépare normalement les répertoires d’un nom de fichier sous Linux?

94
subcan

La réponse est que vous ne pouvez pas, sauf si votre système de fichiers a un bogue. Voici pourquoi:

Il existe un appel système pour renommer votre fichier défini dans fs/namei.c appelé renameat:

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

Lorsque l'appel système est appelé, il effectue une recherche de chemin (do_path_lookup) sur le nom. Continuez à suivre cela, et nous arrivons à link_path_walk qui a ceci:

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;
...

Ce code s'applique à tout système de fichiers. Qu'est-ce que cela signifie? Cela signifie que si vous essayez de passer un paramètre avec un '/' caractère comme le nom du fichier en utilisant des moyens traditionnels, il ne fera pas ce que vous voulez. Il n'y a aucun moyen d'échapper au personnage. Si un système de fichiers "supporte" cela, c'est parce qu'ils:

  • Utilisez un caractère unicode ou quelque chose qui ressemble à une barre oblique mais qui ne l’est pas.
  • Ils ont un bug.

De plus, si vous avez allez et éditez les octets pour ajouter une barre oblique à un nom de fichier, de mauvaises choses se produiraient. C’est parce que vous ne pourriez jamais faire référence à ce fichier par son nom :( puisque vous le feriez à tout moment, Linux supposerait que vous vous référiez à un répertoire inexistant. L’utilisation de la technique 'rm *' ne fonctionnerait pas non plus, puisque bash le développe simplement en fichier. Même rm -rf ne fonctionnerait pas, puisqu’un simple tracé montre comment les choses se passent sous le capot (abrégé):

$ 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
...

Notez que ces appels à unlinkat échoueraient car ils doivent faire référence aux fichiers par leur nom.

119
Robert Martin

Vous pouvez utiliser un caractère Unicode qui s'affiche sous la forme "/" (par exemple ce glyphe apparemment redondant ) en supposant que votre système de fichiers le prenne en charge.

32
Blackle Mori

Cela dépend du système de fichiers que vous utilisez. Parmi les plus populaires:

7
Nicolas

Seulement avec un encodage convenu. Par exemple, vous pourriez convenir que % sera codé comme %% et cela %2F signifiera un /. Tous les logiciels ayant accédé à ce fichier devraient comprendre le codage.

4
David Schwartz

La réponse courte est: non, vous ne pouvez pas. C'est une interdiction nécessaire en raison de la définition de la structure de répertoires.

Et, comme mentionné, vous pouvez afficher un caractère Unicode qui "ressemble" à une barre oblique, mais c'est tout ce que vous obtenez.

1
keyser

En général, c'est une mauvaise idée d'essayer d'utiliser des "mauvais" caractères dans un nom de fichier. même si vous le gérez d'une manière ou d'une autre, il est difficile d'utiliser le fichier ultérieurement. Le séparateur de système de fichiers ne va pas fonctionner du tout. Il va donc falloir choisir une autre méthode.

Avez-vous envisagé de coder l'URL de l'URL, puis de l'utiliser comme nom de fichier? Le résultat devrait être correct comme un nom de fichier, et il est facile de reconstruire le nom à partir de la version encodée.

Une autre option consiste à créer un index - créez le nom de fichier de sortie en utilisant la méthode de votre choix - noms numérotés séquentiellement, hachages SHA1, etc. - puis écrivez un fichier avec la paire nom de fichier/URL générée. Vous pouvez enregistrer cela dans un hachage et l'utiliser pour effectuer une recherche d'URL en nom de fichier ou inversement avec la version inversée du hachage. Vous pouvez l'écrire et le recharger ultérieurement si nécessaire.

0
Joe McMahon