L'espace n'est-il pas autorisé dans un nom de file?

Il est dit que sur Unix et Linux en général, vous devriez éviter d'avoir des espaces dans un nom de file d'un file (file ordinaire, dir, lien, file de périphérique, …).

Mais je le fais tout le time. Pour un nom de file avec un espace à l'intérieur,

  • Dans Nautilus, le caractère d'espace est affiché comme un espace.
  • Dans le terminal Bash, j'utilise \ pour représenter un espace, ou je joins le nom de file à l'intérieur d'une paire de guillemets doubles.
  • dans les files de certaines applications (Nautilus, pas sûr que OS le fasse aussi), le nom du file est écrit avec l'espace remplacé par %20 .

Un espace n'est-il pas vraiment autorisé dans un nom de file?

Comment utilisez-vous ou gérez-vous correctement un espace dans un nom de file?

Les espaces, et en fait tous les caractères sauf / et NUL, sont autorisés dans les noms de files. La recommandation de ne pas utiliser d'espaces dans les noms de files provient du danger qu'ils pourraient être mal interprétés par un logiciel qui les supporte mal. On peut soutenir que ce logiciel est buggé. Mais il est aussi possible que les langages de programmation tels que les scripts de shell facilitent l'écriture de logiciels qui se cassent lorsqu'ils sont présentés avec des noms de files contenant des espaces et ces bogues ont tendance à glisser parce que les développeurs utilisent des noms de files leur.

Les espaces remplacés par %20 ne sont pas souvent visibles dans les noms de files. C'est principalement utilisé pour les URL (web). Bien qu'il soit vrai que le encoding% des URLs se fait parfois dans les noms de files, souvent par accident.

Les espaces sont autorisés dans les noms de files, comme vous l'avez observé.

Si vous regardez l'input «most UNIX filesystems» de ce graphique dans wikipedia , vous remarquerez:

  • Tout jeu de caractères 8 bits est autorisé. Nous pouvons également sous-estimer l'ASCII 7 bits sous ce parapluie, puisqu'il s'agit d'un sous-set de différents sets de 8 bits et qu'il est toujours implémenté en utilisant des octets de 8 bits.

  • Les seuls caractères interdits sont / et "null". "Null" se réfère à un octet zéro, mais ceux-ci ne sont pas autorisés dans datatables text de toute façon.

Cependant , si vous utilisez le shell, vous remarquerez peut-être qu'il y a des caractères qui créeront un problème, le plus significatif * , qui est un opérateur de globulation POSIX.

En fonction de la façon dont vous souhaitez définir «tracas», vous pouvez inclure des espaces (espaces, tabulations, nouvelles lignes, etc.), car cela crée un besoin de citation avec "" . Mais c'est inévitable, puisque les espaces sont autorisés, alors …

Comment utilisez-vous ou gérez-vous correctement un espace dans un nom de file?

Dans un context shell / command line, encapsulez le nom de file en guillemets simples ou doubles (mais notez qu'ils ne sont pas les mêmes problèmes de WRT), ou échappez les espaces avec \ , par exemple:

 > foo my\ file\ with\ spaces\ in\ the\ name 

La raison en est en grande partie historique – Dans la nuit des time, les espaces n'étaient pas autorisés dans les noms de files, donc les espaces étaient utilisés comme séparateurs de mots-keys / noms de files. Les futurs interpréteurs de shell devaient être compatibles avec les anciens scripts, et ainsi nous sums coincés avec le mal de tête que nous avons aujourd'hui.

Les développeurs de process qui n'ont pas besoin de traiter beaucoup avec les humains peuvent rendre les choses beaucoup plus faciles en abandonnant les espaces. Apple le fait, le contenu de / System / Library / CoreServices / contient très peu d'espaces, les programmes avec des espaces sont ouverts au nom de l'user, etWouldLookStrangeIfCamelCased. Les paths unix-only similaires évitent également les espaces.

(anecdote quelque peu connexe: au milieu des années 90, un drone Windows disait "Nommez une chose que vous pouvez faire sur un Mac que je ne peux pas faire sur Windows" -> "Utiliser 12 caractères dans un nom de file" -> Silence. aussi possible dans ces 12 caractères)

Donc, oui, comme il est dit plusieurs fois ailleurs, un nom de file peut contenir presque n'importe quel caractère. Mais il faut dire qu'un nom de file n'est pas un file. Il a un certain poids en tant qu'atsortingbut de file, car vous avez généralement besoin d'un nom de file pour ouvrir un file, mais le nom d' un file pointe uniquement vers le file réel. C'est un lien, stocké dans le directory qui l'a enregistré, à côté du numéro d'inode – qui est une approximation beaucoup plus proche d'un file réel .

Donc, vous savez, appelez-le comme vous voulez. Le kernel ne s'en soucie pas – toutes les references de files qu'il traitera traiteront de vrais nombres d'inodes de toute façon. Le nom de file est une chose pour la consommation humaine – si vous voulez en faire une chose folle, eh bien, c'est votre système de files. Ici, je vais faire des trucs fous:

Tout d'abord, je vais créer 20 files, et les nommer avec rien d'autre que des espaces, chaque nom de file contenant un espace de plus que le dernier:

 until [ $((i=$i+1)) -gt 20 ] do v=$v' ' && touch ./"$v" done 

C'est un peu drôle. Regardez mes ls :

 ls -d ./* ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ ./ 

Maintenant, je vais mettre en miroir ce directory:

 set -- * ; mkdir ../mirror ls -i1qdU -- "$@" | sh -c 'while read inum na do ln -T "$1" ../mirror/$inum shift ; done' -- "$@" ls -d ../mirror/* 

Voici le contenu de ../mirror/ :

 ../mirror/423759 ../mirror/423764 ../mirror/423769 ../mirror/423774 ../mirror/423760 ../mirror/423765 ../mirror/423770 ../mirror/423775 ../mirror/423761 ../mirror/423766 ../mirror/423771 ../mirror/423776 ../mirror/423762 ../mirror/423767 ../mirror/423772 ../mirror/423777 ../mirror/423763 ../mirror/423768 ../mirror/423773 ../mirror/423778 

Ok, mais peut-être que vous requestz – mais à quoi cela sert-il? Comment pouvez-vous dire lequel est lequel? Comment pouvez-vous être sûr que vous avez lié le bon numéro d'inode au bon nom de file?

Bien…

 echo "heyhey" >>./' ' tgt=$(ls -id ./' ') cat ../mirror/${tgt%% .*} \ $(ls -1td ../mirror/* | head -n1) 

SORTIE

 heyhey heyhey 

Voir, le numéro d'inode contenu dans ../mirror/"${tgt%% .*}" Et celui référencé par ./' ' rapportent au même file. Ils décrivent le même file. Ils le nomment, mais rien de plus. Il n'y a pas vraiment de mystère, juste quelques inconvénients que vous pourriez avoir pour vous-même, mais qui finiront par avoir peu ou pas d'effet sur le fonctionnement de votre système de files unix à la fin.