GNU/Linux >> Tutoriels Linux >  >> Linux

Certains dossiers et/ou fichiers sur disque dur externe sont accessibles sous Linux mais pas sous macOS et Windows

Je poste cette réponse juste pour dire comment le problème a été résolu, résumant ainsi les commentaires faits à la question d'origine, ce qui pourrait être utile à d'autres.

J'ai résolu le problème sous Linux, où ces dossiers avaient été créés, simplement en raccourcissant le titre de deux ou trois des fichiers vidéo, qui avaient des noms longs mais pas de caractères évidemment étranges comme des virgules, des crochets, etc. J'ai également changé le dossier noms - même s'ils n'avaient rien de spécial. Les remettre en place n'a pas reproduit le problème.

Ainsi, soit les noms de dossier avaient un mauvais caractère qui n'était pas visible en tant que tel sous Linux, soit les mauvais caractères dans certains des trois fichiers qui ont été renommés ont rendu l'ensemble du dossier invisible sous Mac et tous son contenu est illisible sous Windows.

C'est la chose la plus étrange qui, avant de renommer les dossiers et les trois fichiers, aucun des fichiers étaient lisibles sous Windows.

C'était peut-être le cas, comme @Giacomo1968 l'a dit dans un commentaire :

"... un caractère "fantôme" dans le nom de fichier d'origine... Quelque chose comme un retour chariot ou un espace insécable qui était géré dans un sens sous Linux, mais étouffé sur d'autres systèmes."

Le fait est qu'avant de résoudre le problème, j'ai essayé de lire dans Windows d'autres fichiers que ceux qui ont finalement été renommés. Le caractère fantôme aurait également pu se trouver dans les noms de dossier.

Cela m'est arrivé à nouveau sur un nouveau lecteur formaté en exFAT avec d'autres fichiers dans un dossier à propos duquel une erreur a été signalée dans Linux par le gestionnaire de fichiers Nemo lors de la copie (quelque chose comme "impossible de créer un fichier"), mais en fait tout avait l'air bien sur Linux. Ce dossier a été vu mais est resté complètement inaccessible sous Windows (je ne me souviens pas exactement du message d'erreur, quelque chose à propos d'un fichier ou d'un dossier n'existant pas), et il a été vu sur un Mac, à l'exception d'un seul fichier, qui est resté invisible. Après avoir renommé sous Linux le dossier et le fichier avec le même nom tout s'est passé normalement !

Je soupçonne maintenant que la cause du problème initial signalé dans la question, et la création d'un mauvais personnage "fantôme", était une erreur lors d'un processus de copie ou le collage en titre de texte copié depuis des pages internet (où ce qui ressemble à un espace, par exemple, est en fait autre chose). Cela m'a été suggéré par le fait que lors de la copie avec Double Commander sous Linux, il a signalé des erreurs détaillées sur certains noms qui incluent des espaces qui auraient pu être des caractères de tabulation ou quelque chose de similaire.

Au final, la meilleure solution pour copier était d'utiliser Double Commander sous Linux qui indiquait très clairement le nom du fichier qui posait problème.

Copier/coller du texte Internet lors de la dénomination de fichiers ou de dossiers doit être fait avec prudence.


Le fonctionnement des noms de fichiers/dossiers sous Windows est expliqué sur le site Web de Microsoft. Cependant, cela ne donne qu'un aperçu de la vérité globale.

NB :Je ne le ferai pas discuter de l'aspect des problèmes de page de code qui peuvent survenir de la manière dont un système "étranger" accède à un volume NTFS. Je pense que cela est suffisamment couvert dans les commentaires et l'autre réponse. Je me limiterai en grande partie aux deux aspects suivants :

  • Limites de la longueur des noms de chemin
  • combinaisons de caractères difficiles/impossibles d'accès depuis le sous-système Win32

En ce qui concerne le système de fichiers, je me limiterai à NTFS, tout comme la question. Considérez le commentaire suivant du site Web lié ci-dessus :

Ne terminez pas un nom de fichier ou de répertoire par un espace ou un point. Bien que le système de fichiers sous-jacent puisse prendre en charge de tels noms, le shell Windows et l'interface utilisateur ne le font pas .

Maintenant, nous devons d'abord clarifier une partie de la terminologie. Nous traitons de différentes ... couches, est probablement un terme approprié :

  • système de fichiers, par ex. NTFS
  • Gestionnaire d'objets NT et autres fonctionnalités du noyau, mais en ce qui concerne les noms surtout le gestionnaire d'objets
    (si vous voulez le regarder, utilisez un outil comme WinObj)
  • Sous-système Win32 (c'est ce que la déclaration ci-dessus appelle "Windows shell et interface utilisateur")
  • Un autre "méta-aspect" serait la version du système d'exploitation, car la longueur du chemin pris en charge peut varier

Une bonne méthode pour jouer avec cela est un partage Samba qui prétend être NTFS côté client. Mais un volume Windows NTFS fera également l'affaire. Nous serons sous Windows et "jouerons" depuis la ligne de commande (appuyez sur Win +R et tapez cmd , puis appuyez sur Entrée ).

Volume NTFS local

Supposons que nous voulions créer un nom de fichier invalide (remarquez le point de fin ? !) :

echo NONSENSE > text.txt.

En essayant cela, le résultat sera en effet test.txt , pas test.txt. . Le sous-système Win32 (csrss.exe) nous a empêché de faire des choses stupides. Hum, intéressant, hein ?

Considérez cette autre déclaration :

N'utilisez pas les noms réservés suivants pour le nom d'un fichier :

CON , PRN , AUX , NUL , COM1 , COM2 , COM3 , COM4 , COM5 , COM6 , COM7 , COM8 , COM9 , LPT1 , LPT2 , LPT3 , LPT4 , LPT5 , LPT6 , LPT7 , LPT8 , et LPT9 . Evitez également ces noms suivis immédiatement d'une extension; par exemple, NUL.txt n'est pas recommandé.

Hum, NUL semble amusant. Nous savons qu'en tant que substitut de /dev/null sur les systèmes unixoïdes, hérités de l'époque du DOS.

echo NONSENSE > NUL

Ah, c'est vrai. C'est un substitut de /dev/null , donc la sortie sera avalée. Mais ne pas utiliser semble tellement tentant. Utilisons donc les informations résumées d'un article de blog Project Zero, section "Appareil local".

Bref intermède :%CD%

Si vous n'êtes pas trop familier avec la ligne de commande Windows classique (cmd.exe ), la variable spéciale %CD% nous donnera le chemin absolu vers le répertoire de travail actuel. Gardez cela à l'esprit pour la section suivante. Donc, si vous étiez actuellement dans C:\test , la commande echo %CD% donnerait la sortie C:\test . C'est un raccourci pratique pour nos expériences.

Comme nous pouvons le constater dans l'article Project Zero, il existe plusieurs façons d'éviter les conversions de noms de chemin au niveau du sous-système Win32. Une de ces méthodes est le préfixe \\?\ qui en interne directement se traduit par \??\ , qui sur les nouvelles versions de Windows est identique à \GLOBAL??\ . C'est ce qu'on appelle un répertoire d'objets (veuillez ne pas le confondre avec les entités du système de fichiers , malgré la terminologie similaire !). Encore une fois, WinObj et des outils similaires vous permettent d'étudier l'espace de noms du gestionnaire d'objets.

Interlude :espaces de noms et "trucs" du serveur de terminaux

Quiconque a jeté un coup d'œil à l'histoire de Windows NT, et que Windows 10 remonte à NT, se souviendra d'une époque où vous deviez autoriser séparément les services de terminaux. C'est à dire. la possibilité de se connecter à distance à une seule machine avec différents utilisateurs.

Je pense que c'est Windows XP qui a finalement apporté cela aux masses en permettant de rester connecté avec plusieurs comptes d'utilisateurs simultanément ("changement d'utilisateur"), et probablement Windows 2000 ou 2003 Server l'a inclus dans l'édition standard, même si les CAL étaient nécessaires au-delà du minimum de « sièges » inclus par défaut.

C'est là que la distinction entre \?? et \GLOBAL?? est originaire. \GLOBAL?? est la vue des noms de périphériques "DOS" partagés par tous sessions de connexion.

\?? est de nos jours vu dans le lien symbolique (encore une fois, pas une entité du système de fichiers ! ) appelé \DosDevices , ce qui donne un indice sur son origine. C'est là que les noms de périphériques "DOS", tels que C: ou les mappages de lecteur réseau résident. Sur un système moderne C: à son tour serait un lien symbolique vers \Device\HarddiskVolume1 (ou similaire). C'est alors généralement un réel objet de périphérique qui a été créé par un pilote dans la pile de pilotes de stockage, dans ce cas, il devrait être le pilote du système de fichiers NTFS.

Ainsi, lorsque vous double-cliquez sur C:\Windows\explorer.exe ce qui se passe en interne, c'est que le chemin est converti :

  • Au niveau du sous-système Win32, le changement habituel consistera à ajouter \??\ .
  • Le gestionnaire d'objets développera alors le \??\C: .
    • Premier \??\ se retrouve dans l'espace de noms de périphérique "DOS" pour votre session de connexion (voir la remarque ci-dessous)
    • Finalement, le gestionnaire d'objets trouve quelque chose comme \??\C: étant équivalent à \GLOBAL??\C: qui - comme nous l'avons vu plus haut - équivaut à \Device\HarddiskVolume1 .

Le gestionnaire d'objets passera alors le reste du chemin \Windows\explorer.exe au conducteur responsable de l'objet périphérique \Device\HarddiskVolume1 , en s'assurant que le pilote sait quel objet périphérique a été référencé. Et ce pilote saura comment, à l'intérieur de son propre espace de noms, gérer ce reste particulier du chemin.

Remarque : Lorsque vous vous référez à \?? en interne, vous vous retrouvez avec une vue des périphériques "DOS" de votre session de connexion locale. Cela peut être mieux expliqué avec des lecteurs réseau mappés. Disons que vous avez une lettre de lecteur X: mappé pour un partage distant. Et disons que vous utilisez le "changement d'utilisateur" ou que cela s'exécute sur un serveur de terminaux costaud où deux cents autres utilisateurs sont connectés simultanément. Nous avons deux problèmes à résoudre dans un tel scénario. Alors que le lecteur système (par exemple, le disque physique) peut être partagé par tout le monde, quelqu'un des ventes peut avoir mappé "le part des ventes" comme X: et quelqu'un du développement a peut-être cartographié "le partage de développement". Il en va de même pour une "lettre de lecteur" attribuée via subst . Cela devrait expliquer pourquoi il ne peut y avoir un seul espace de noms global pour les noms de périphériques "DOS", qui convient à tout le monde.

Notre objectif était donc de créer un fichier (ou répertoire) nommé NUL et le sous-système Win32 ne nous a pas laissé faire. Il a simplement avalé la sortie et le fichier n'a jamais été créé dans notre répertoire de travail. Cependant, en tirant parti des informations de l'article lié ci-dessus et de l'intermède précédent, nous pouvons contourner ce problème en évitant ces conversions de chemin embêtantes au niveau du sous-système en émettant un :

echo NONSENSE > \\?\%CD%\NUL

Pour rappel, %CD% développe le chemin absolu du répertoire de travail actuel et, en supposant qu'il s'agit de C:\test , la commande ci-dessus est équivalente à echo NONSENSE > \\?\C:\test\NUL .

Et voilà, un rapide dir prouve que le fichier a été créé. Et si nous essayons cela avec d'autres noms "réservés", cela fonctionne bien aussi.

Veuillez noter que vous pouvez également utiliser le réel forme de chemin NT natif (\?? au lieu de \\? ) pour le même effet :

echo NONSENSE > \??\%CD%\NUL

Propre.

Alors que diriez-vous de revoir la tentative de point de fin, mais en donnant le chemin complet sans que le sous-système Win32 n'interfère ? :

echo ILLEGAL TRAILING DOT > \??\%CD%\test.txt.

Voila, ça marche, comme un rapide dir /b prouve :

C:\test>dir /b
CON
NUL
test.txt
test.txt.

Interlude :chemins UNC (Universal Naming Convention)

Ce sujet est traité plus en détail dans cet article de Project Zero, mais il suffit de dire qu'il existe une forme spéciale de chemin qui ressemble assez à ce que nous venons d'utiliser ci-dessus :\\.\C:\Windows\explorer.exe serait un exemple.

N'oubliez pas que chaque fois que vous êtes bloqué sur l'écran de connexion, sans vous souvenir du nom de la machine locale de la machine, et qu'il utilise par défaut le domaine dont il est membre ? Un moyen simple de se référer à la machine actuelle sans même utiliser son vrai nom est .\username , permettant de référencer l'utilisateur username sur la machine actuelle .

Le . en \\.\C:\Windows\explorer.exe est à comprendre de la même manière. En effet, ce que vous dites est \\. sur la machine actuelle \C: sur le lecteur C: chemin d'accès \Windows\explorer.exe ... et les différentes fonctionnalités du système d'exploitation sont liées les unes aux autres pour que cela se produise.

Attention :Les chemins UNC suivent un ensemble de règles différent, c'est pourquoi je ne les mentionne que. Lisez l'article lié et le lien vers la documentation Microsoft si vous souhaitez plus de détails.

Maintenant que nous avons enfin créé un fichier "impossible" test.txt. , jetons-y un coup d'œil, d'accord ?

C:\test>type test.txt
NONSENSE

Que diable? Je me souviens clairement avoir fait écho au ILLEGAL TRAILING DOT dans ce fichier.

Ah, bien sûr. Tout comme lorsque nous avons initialement essayé de créer test.txt. le sous-système Win32 est intervenu à nouveau et a "utilement" converti notre nom en test.txt . Nous examinons donc en fait \??\%CD%\test.txt au lieu de \??\%CD%\test.txt. .

Donc ça devrait faire :

C:\test>type \??\%CD%\test.txt.
ILLEGAL TRAILING DOT

Beaucoup mieux. Le problème est que tous les programmes ne géreront pas notre contournement sournois des conversions de noms de chemin Win32 aussi gracieusement que cmd.exe . Supposons que nous voulions ouvrir le Bloc-notes :

C:\test>notepad \??\%CD%\test.txt.

Dang, nous voyons la boîte de message suivante :

Ainsi, bien qu'il existe des moyens de contourner certains des restrictions imposées par le sous-système Win32, l'utilité de ces méthodes est limitée et discutable.

Remarque  :lecteurs qui développent aussi logiciel sur/pour Windows peut rappeler que l'utilisation du préfixe \\?\ autorisé à contourner le MAX_PATH limite (auparavant 260, essentiellement 255 plus \\?\ et un \0 de terminaison ). Vous savez maintenant pourquoi cela nous permet d'utiliser environ 32767 caractères. Depuis que UCS-2 a été remplacé par UTF-16 (je pense dans XP), la modification des chemins au niveau du gestionnaire d'objets n'est qu'un problème. Une autre est qu'en UTF-16, un point de code peut prendre plus de 16 bits (alias wchar_t ou WCHAR ), une fois que vous avez quitté le BMP.

Quoi qu'il en soit, la ligne de commande (cmd.exe ) vous donne tous les outils pour accéder et vous débarrasser des fichiers que vous avez pu créer à partir de Windows en premier lieu.

Partage Linux/Samba, prétendant être NTFS

Partons maintenant du lecteur local et considérons un lecteur réseau mappé Z: , fourni par Samba 4.x, qui imite un lecteur NTFS en ce qui concerne Windows.

Cette expérience offre quelques informations supplémentaires, car nous pouvons créer des fichiers selon les règles du côté Linux et n'avons pas à nous inquiéter de ne pas pouvoir y accéder depuis le côté Windows.

  • Le lecteur mappé est Z: et nous serons en Z:\test côté Windows
  • Du côté Linux, le volume a été formaté en tant que btrfs
    L'article de Wikipédia nous indique tous les caractères autres que / et \0 (alias caractère ASCII NUL) sont autorisés ! Alors ça devrait être amusant.

Voici quelques noms de fichiers extravagants qui devraient (ou du moins pourraient) être difficiles d'accès du côté Windows, en utilisant Bash sur Ubuntu 20.04 du côté Linux pour les créer :

  • :.txt (créé avec echo "$RANDOM" > \:.txt )
  • ???.txt (créé avec echo "$RANDOM" > \?\?\?.txt )
  • .txt (créé avec echo "$RANDOM" > .txt )
  • *.txt (créé avec echo "$RANDOM" > \*.txt )
  • \.txt (créé avec echo "$RANDOM" > \\.txt )
  • ".txt (créé avec echo "$RANDOM" > \".txt )
  • >.txt (créé avec echo "$RANDOM" > \>.txt )
  • <.txt (créé avec echo "$RANDOM" > \<.txt )
  • |.txt (créé avec echo "$RANDOM" > \|.txt )

Cela devrait couvrir à peu près toutes les bases, en fait, à la réflexion, les emoji peuvent même ne pas être un problème du tout. Les barres obliques sont également interdites sur NTFS, mais cela vaut également pour btrfs/POSIX/SUS.

Preuve côté Linux :

$ find -type f -printf '%P\n'
:.txt
???.txt
.txt
*.txt
\.txt
".txt
>.txt
<.txt
|.txt

Voyons maintenant si et à quoi nous pouvons accéder du côté Windows...

Z:\test>dir /b
_2X68P~X.TXT
_2X68Q~5.TXT
_2X68Q~9.TXT
_2X68Q~B.TXT
_2X68Q~D.TXT
_2X68R~7.TXT
_2X68S~3.TXT
_67V3K~2.TXT
.txt

Capture d'écran comme preuve :

Ohhhhh ! À droite, l'héritage DOS de Windows frappe à nouveau. NTFS - à moins de le désactiver activement - a la capacité de créer des noms de fichiers courts dits 8.3, conformes aux exigences de nom de fichier DOS.

Et c'est ainsi que nous pouvons accéder aux noms de fichiers invalides malgré tout.

Conclusion

Rappelez-vous maintenant que la question concernait un lecteur NTFS externe, c'est-à-dire local. Cela signifie que les règles que nous venons d'observer pour les partages Samba peuvent ne pas s'appliquer ici.

Selon le pilote utilisé pour stocker ces fichiers (qui peut varier selon la version de Linux/macOS, par exemple ntfs-3g ou le pilote tiers utilisé, par exemple le pilote de Paragon), je vois les causes possibles suivantes après avoir examiné les expériences ci-dessus :

  1. le nom du fichier contenait un : , " ou ? ... cela me semble le plus probable, étant donné que j'avais moi-même accidentellement copié et collé des titres d'ebook contenant ces caractères. Nous pouvons à peu près exclure / et les autres caractères "interdits" sont au moins moins probables.
  2. les côtés Windows et macOS voient le nom invalide, tentent de regarder le nom DOS 8.3, mais aucun n'a été généré. Cela dépend quelque peu de la version exacte de Windows et de sa configuration et comme je n'ai pas d'appareils macOS autour, je ne peux pas non plus tester ce scénario. De plus, je ne sais pas si sur un système Windows où les noms 8.3 sont activés Windows irait rétroactivement et générerait un nom 8.3 si, par exemple, le côté Linux sautait cette partie. Parce que si je me souviens bien, le pilote NTFS décide si l'enregistrement respectif ("attribut") est rempli.
  3. la longueur du nom du chemin a été dépassée. Je pense que dépasser la longueur des segments de chemin est une impossibilité, car NTFS ne vous permet pas de stocker plus de 255 valeurs 16 bits pour un segment de chemin, mais la longueur totale du chemin peut également avoir été dépassée (voir ce lien).

Pour le premier scénario, je recommanderais d'utiliser fslint du côté Linux pour nettoyer les noms de fichiers (et de dossiers). D'autres outils similaires existent et YMMV, faites votre choix.

J'espère que cela t'aides. Il m'a fallu assez de temps pour mettre mes pensées par écrit.

Autres lectures

  • Nommer les fichiers, les chemins et les espaces de noms
  • Le guide définitif sur la conversion de chemin Win32 vers NT

Linux
  1. Comment configurer le serveur SAMBA et transférer des fichiers entre Linux et Windows

  2. Linux – Répertoires standard et/ou communs sur les systèmes Unix/linux ?

  3. Metamorphose 2 - Renommer par lots vos fichiers et dossiers sous Linux

  4. Que sont les fichiers /dev/zero et /dev/null sous Linux

  5. Dans quels langages Windows, Mac OS X et Linux sont-ils écrits ?

Rechercher et supprimer le fichier le plus ancien s'il y a plus de X fichiers dans un répertoire sous Linux

Empêcher les fichiers et les dossiers d'être supprimés ou modifiés accidentellement sous Linux

Comment ouvrir des fichiers et des dossiers en tant qu'administrateur dans Nautilus File Manager sous Linux

Comment masquer des dossiers et des fichiers sous Linux à l'aide d'un fichier texte

Économisez de l'espace en compressant les fichiers et les dossiers sous Linux

Partage de fichiers entre Linux Mint et Windows 10