GNU/Linux >> Linux Esercitazione >  >> Linux

Alcune cartelle e/o file sull'HDD esterno sono accessibili su Linux ma non su macOS e Windows

Pubblico questa risposta solo per dire come è stato risolto il problema, riassumendo così i commenti fatti alla domanda originale, che potrebbero essere utili ad altri.

Ho risolto il problema in Linux, dove erano state create quelle cartelle, semplicemente accorciando il titolo di due o tre dei file video, che avevano nomi lunghi ma senza caratteri ovviamente strani come virgole, parentesi ecc. Ho cambiato anche la cartella nomi, anche se non avevano niente di speciale. Cambiarli di nuovo non ha riprodotto il problema.

Quindi, o i nomi delle cartelle avevano qualche carattere sbagliato che non era visibile come tale su Linux, oppure i caratteri errati in alcuni dei tre file che sono stati rinominati rendevano l'intera cartella invisibile in Mac e tutti contiene contenuti non riproducibili in Windows.

Questa è la cosa più strana che, prima di rinominare le cartelle ei tre file, nessuno dei file era riproducibile in Windows.

Potrebbe essere stato, come ha detto @Giacomo1968 in un commento:

'...un carattere "fantasma" nel nome del file originale... Qualcosa come un ritorno a capo o uno spazio unificatore che veniva gestito in un modo in Linux, ma soffocato su altri sistemi.'

Il fatto è che prima di risolvere il problema ho provato a riprodurre in Windows file diversi da quelli che alla fine sono stati rinominati. Il carattere fantasma potrebbe essere stato anche nei nomi delle cartelle.

Mi è successo di nuovo su una nuova unità formattata come exFAT con altri file in una cartella per la quale è stato segnalato un errore in Linux dal file manager Nemo durante la copia (qualcosa del tipo "impossibile creare file"), ma poi in realtà sembrava tutto a posto su Linux. Quella cartella è stata vista ma è rimasta completamente inaccessibile in Windows (non ricordo esattamente il messaggio di errore, qualcosa su file o cartella non esistente), ed è stata vista su Mac, tranne un singolo file, che è rimasto invisibile. Dopo aver rinominato in Linux la cartella e il file con lo stesso nome tutto è andato normalmente!

Sospetto ora che la causa del problema iniziale riportato nella domanda, e la creazione di un cattivo carattere "fantasma", sia stato un errore durante un processo di copiatura o l'incollaggio nel titolo di testo copiato da pagine internet (dove quello che sembra uno spazio, ad esempio, è in realtà qualcos'altro). Questo mi è stato suggerito dal fatto che durante la copia con Double Commander in Linux riportava errori dettagliati su alcuni nomi che includevano spazi che avrebbero potuto essere caratteri di tabulazione o qualcosa di simile.

Alla fine, la soluzione migliore per copiare era usare Double Commander in Linux che indicava molto chiaramente il nome del file che aveva problemi.

Il copia/incolla del testo Internet quando si nominano file o cartelle deve essere fatto con cautela.


Il modo in cui i nomi di file/cartelle funzionano su Windows è discusso sul sito Web di Microsoft. Tuttavia, ciò fornisce solo un assaggio della verità complessiva.

NB:non discutere l'aspetto dei problemi di codepage che possono derivare dal modo in cui un sistema "estraneo" accede a un volume NTFS. Penso che questo sia sufficientemente trattato nei commenti e nell'altra risposta. Mi limiterò in gran parte ai seguenti due aspetti:

  • limiti di lunghezza del nome di percorso
  • combinazioni di caratteri a cui è difficile/impossibile accedere dal sottosistema Win32

Per quanto riguarda il file system mi limiterò a NTFS, proprio come la domanda. Si consideri il seguente commento dal sito web collegato sopra:

Non terminare il nome di un file o di una directory con uno spazio o un punto. Sebbene il file system sottostante possa supportare tali nomi, la shell e l'interfaccia utente di Windows non lo supportano .

Ora, dobbiamo prima chiarire parte della terminologia. Abbiamo a che fare con vari... strati, è probabilmente un termine appropriato:

  • file system, ad es. NTFS
  • Gestore di oggetti NT e altre funzionalità del kernel, ma quando si tratta di nomi principalmente il gestore dell'oggetto
    (se vuoi guardarlo, usa uno strumento come WinObj)
  • Sottosistema Win32 (questo è ciò a cui si riferisce l'istruzione precedente come "shell e interfaccia utente di Windows")
  • Un altro "meta aspetto" sarebbe la versione del sistema operativo, poiché la lunghezza del percorso supportata può variare

Un bel metodo per giocare con questo è una condivisione Samba che finge di essere NTFS sul lato client. Ma andrà bene anche un volume Windows NTFS. Saremo su Windows e "giocheremo" dalla riga di comando (premi Win +R e digita cmd , quindi premi Invio ).

Volume NTFS locale

Supponiamo di voler creare un nome di file non valido (notate il punto finale?!):

echo NONSENSE > text.txt.

Quando si tenta di farlo, il risultato sarà effettivamente test.txt , non test.txt. . Il sottosistema Win32 (csrss.exe) ci ha impedito di fare cose stupide. Hmm, interessante, eh?

Considera quest'altra affermazione:

Non utilizzare i seguenti nomi riservati per il nome di un file:

CON , PRN , AUX , NUL , COM1 , COM2 , COM3 , COM4 , COM5 , COM6 , COM7 , COM8 , COM9 , LPT1 , LPT2 , LPT3 , LPT4 , LPT5 , LPT6 , LPT7 , LPT8 e LPT9 . Evita anche questi nomi seguiti immediatamente da un'estensione; ad esempio, NUL.txt non è raccomandato.

Uhm, NUL sembra divertente. Sappiamo che è un sostituto di /dev/null su sistemi unixoid, ereditati dai tempi del DOS.

echo NONSENSE > NUL

Oh giusto. È un sostituto di /dev/null , quindi l'output verrà inghiottito. Ma non usare suona così molto allettante. Quindi usiamo le informazioni riassunte da un articolo del blog di Project Zero, sezione "Dispositivo locale".

Breve intermezzo:%CD%

Se non hai molta familiarità con la classica riga di comando di Windows (cmd.exe ), la variabile speciale %CD% ci darà il percorso assoluto della directory di lavoro corrente. Tienilo a mente per la sezione seguente. Quindi, se ti trovavi attualmente all'interno di C:\test , il comando echo %CD% produrrebbe l'output C:\test . È una comoda scorciatoia per i nostri esperimenti.

Come possiamo ricavare dall'articolo di Project Zero, esistono diversi modi per evitare le conversioni dei nomi di percorso a livello di sottosistema Win32. Uno di questi metodi è il prefisso \\?\ che internamente direttamente si traduce in \??\ , che nelle versioni più recenti di Windows è identico a \GLOBAL??\ . Questa è chiamata directory di oggetti (per favore non confonderla con le entità del file system , nonostante la terminologia simile!). Ancora una volta, WinObj e strumenti simili ti consentono di esaminare lo spazio dei nomi del gestore oggetti.

Interlude:namespace e "cose" del terminal server

Chiunque abbia dato un'occhiata alla storia di Windows NT e Windows 10 fa risalire le sue radici a NT, ricorderà un momento in cui dovevi concedere in licenza separatamente i servizi terminal. Cioè. la possibilità di connettersi a una singola macchina in remoto con diversi utenti.

Penso che sia stato Windows XP a portare questo finalmente per le masse consentendo di rimanere connessi con più account utente contemporaneamente ("cambio utente"), e probabilmente Windows 2000 o 2003 Server lo includevano nell'edizione standard, anche se le CAL erano necessari oltre i "posti" minimi inclusi per impostazione predefinita.

Qui sta la distinzione tra \?? e \GLOBAL?? ha origine. \GLOBAL?? è la visualizzazione dei nomi dei dispositivi "DOS" condivisi da tutti sessioni di accesso.

\?? è oggi visto nel collegamento simbolico (di nuovo, non un'entità del file system! ) chiamato \DosDevices , che fornisce un indizio sulla sua origine. Qui è dove i nomi dei dispositivi "DOS", come C: o le mappature delle unità di rete risiedono. Su un sistema moderno C: a sua volta sarebbe un collegamento simbolico a \Device\HarddiskVolume1 (o simili). Questo di solito è un effettivo oggetto dispositivo che è stato creato da un driver nello stack del driver di archiviazione, in questo caso dovrebbe essere il driver del file system NTFS.

Quindi, quando fai doppio clic su C:\Windows\explorer.exe ciò che accade internamente è che il percorso viene convertito:

  • A livello di sottosistema Win32 la solita modifica sarà quella di anteporre \??\ .
  • Il gestore oggetti espanderà quindi il \??\C: .
    • Primo \??\ finisce nello spazio dei nomi del dispositivo "DOS" per la tua sessione di accesso (vedi commento sotto)
    • Alla fine il gestore dell'oggetto scopre qualcosa come \??\C: equivale a \GLOBAL??\C: che - come abbiamo visto sopra - equivale a \Device\HarddiskVolume1 .

Il gestore oggetti passerà quindi il resto del percorso \Windows\explorer.exe al driver responsabile dell'oggetto dispositivo \Device\HarddiskVolume1 , assicurandosi che il driver sappia a quale oggetto dispositivo è stato fatto riferimento. E quel driver saprà come gestire quel particolare resto del percorso all'interno del proprio namespace.

Osservazione: Quando fai riferimento a \?? internamente ti ritroverai con una vista dei dispositivi "DOS" della tua sessione di accesso locale. Questo può essere spiegato meglio con le unità di rete mappate. Supponi di avere una lettera di unità X: mappato per una condivisione remota. E supponiamo che tu faccia uso del "cambio utente" o che questo sia in esecuzione su un robusto terminal server in cui sono connessi contemporaneamente altri duecento utenti. Abbiamo due problemi a portata di mano in uno scenario del genere. Sebbene l'unità di sistema (ad esempio il disco fisico) possa essere condivisa da tutti, qualcuno delle vendite potrebbe aver mappato "il quota di vendita" come X: e qualcuno dello sviluppo potrebbe aver mappato "the quota di sviluppo". Lo stesso vale per una "lettera di unità" assegnata tramite subst . Questo dovrebbe spiegare perché non può esistere un unico spazio dei nomi globale per i nomi dei dispositivi "DOS", adatto a tutti.

Quindi il nostro obiettivo era creare un file (o directory) denominata NUL e il sottosistema Win32 non ce lo ha permesso. Ha semplicemente inghiottito l'output e il file non è mai stato creato nella nostra directory di lavoro. Sfruttando le informazioni dall'articolo collegato sopra e dall'intermezzo precedente, tuttavia, possiamo aggirare questo problema eludendo quelle fastidiose conversioni di percorso a livello di sottosistema emettendo un:

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

Come promemoria, %CD% si espande nel percorso assoluto della directory di lavoro corrente e, supponendo che sia C:\test , il comando precedente equivale a echo NONSENSE > \\?\C:\test\NUL .

Ed ecco, un rapido dir dimostra che il file è stato creato. E se lo proviamo con altri nomi "riservati", funziona altrettanto bene.

Tieni presente che puoi anche utilizzare attuale formato del percorso NT nativo (\?? invece di \\? ) per lo stesso effetto:

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

Pulito.

Allora che ne dici di rivisitare il tentativo del punto finale, ma fornendo il percorso completo senza che il sottosistema Win32 interferisca?:

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

Voilà, funziona, come un rapido dir /b dimostra:

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

Interludio:percorsi UNC (Universal Naming Convention)

Questo argomento è trattato in modo più dettagliato nell'articolo di Project Zero, ma basti dire che esiste una forma speciale di percorso che sembra abbastanza simile a quello che abbiamo appena usato sopra:\\.\C:\Windows\explorer.exe sarebbe un esempio.

Ricordi che ogni volta che sei bloccato sulla schermata di accesso, non ricordi il nome della macchina locale della macchina, e per impostazione predefinita è il dominio di cui è membro? Un modo semplice per fare riferimento alla macchina corrente senza nemmeno usare il suo vero nome è .\username , consentendo di fare riferimento all'utente username sulla macchina corrente .

Il . in \\.\C:\Windows\explorer.exe è da intendersi allo stesso modo. In effetti quello che stai dicendo è \\. sulla macchina corrente \C: sull'unità C: percorso di accesso \Windows\explorer.exe ... e le diverse funzionalità del sistema operativo si collegano l'una all'altra per realizzarlo.

Attenzione :i percorsi UNC seguono un diverso insieme di regole, motivo per cui li menziono solo. Leggi l'articolo collegato e il link alla documentazione Microsoft se sei interessato a maggiori dettagli.

Ora che abbiamo finalmente creato un file "impossibile" test.txt. , diamo un'occhiata, va bene?

C:\test>type test.txt
NONSENSE

Che diamine? Ricordo chiaramente di aver ripetuto ILLEGAL TRAILING DOT in quel file.

Ah, certo. Proprio come quando inizialmente abbiamo provato a creare test.txt. il sottosistema Win32 è intervenuto di nuovo e ha "utilmente" convertito il nostro nome in test.txt . Quindi in realtà stiamo guardando \??\%CD%\test.txt invece di \??\%CD%\test.txt. .

Quindi questo dovrebbe fare:

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

Molto meglio. Il problema è che non tutti i programmi gestiranno la nostra subdola elusione delle conversioni dei nomi di percorso Win32 con la stessa grazia di cmd.exe . Supponiamo di voler aprire Blocco note:

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

Dang, possiamo vedere la seguente finestra di messaggio:

Quindi, sebbene ci siano modi per aggirarne alcuni delle restrizioni imposte dal sottosistema Win32, l'utilità di questi metodi è limitata e discutibile.

Nota :lettori che sviluppano software su/per Windows potrebbe ricordarlo usando il prefisso \\?\ permesso di eludere l'MAX_PATH limite (era 260, praticamente 255 più \\?\ e un \0 di chiusura ). Ora sai perché questo ci consente di utilizzare approssimativamente 32767 caratteri. Poiché UCS-2 è stato sostituito con UTF-16 (penso in XP), la modifica del percorso a livello di gestore oggetti non è che un problema. Un altro è che in UTF-16 un punto di codice può occupare più di 16 bit (noto anche come wchar_t o WCHAR ), una volta lasciato alle spalle il BMP.

Ad ogni modo, la riga di comando (cmd.exe ) ti offre tutti gli strumenti per accedere e sbarazzarti dei file che sei stato in grado di creare da Windows in primo luogo.

Condivisione Linux/Samba, che finge di essere NTFS

Partiamo ora dall'unità locale e consideriamo un'unità di rete mappata Z: , fornito da Samba 4.x, che imita un'unità NTFS per quanto riguarda Windows.

Questo esperimento offre qualche spunto in più, perché possiamo creare file secondo le regole del lato Linux e non dobbiamo preoccuparci di non potervi accedere dal lato Windows.

  • L'unità mappata è Z: e saremo in Z:\test sul lato Windows
  • Sul lato Linux il volume è stato formattato come btrfs
    L'articolo di Wikipedia ci dice tutti i caratteri diversi da / e \0 (alias carattere ASCII NUL) sono consentiti! Quindi dovrebbe essere divertente.

Ecco alcuni nomi di file stravaganti a cui dovrebbe (o almeno potrebbe) essere difficile accedere sul lato Windows, utilizzando Bash su Ubuntu 20.04 sul lato Linux per crearli:

  • :.txt (creato con echo "$RANDOM" > \:.txt )
  • ???.txt (creato con echo "$RANDOM" > \?\?\?.txt )
  • .txt (creato con echo "$RANDOM" > .txt )
  • *.txt (creato con echo "$RANDOM" > \*.txt )
  • \.txt (creato con echo "$RANDOM" > \\.txt )
  • ".txt (creato con echo "$RANDOM" > \".txt )
  • >.txt (creato con echo "$RANDOM" > \>.txt )
  • <.txt (creato con echo "$RANDOM" > \<.txt )
  • |.txt (creato con echo "$RANDOM" > \|.txt )

Questo dovrebbe praticamente coprire tutte le basi, in realtà a pensarci bene l'emoji potrebbe non essere nemmeno un problema. Anche le barre in avanti sono vietate su NTFS, ma ciò vale anche per btrfs/POSIX/SUS.

Prova dal lato Linux:

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

Adesso vediamo se e a cosa possiamo accedere lato 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

Screenshot come prova:

Ohhhh! Giusto, l'eredità DOS di Windows colpisce ancora. NTFS, a meno che non venga disabilitato attivamente, ha la capacità di creare i cosiddetti nomi di file brevi 8.3, conformi ai requisiti dei nomi di file DOS.

Ed è così che siamo in grado di accedere comunque ai nomi di file non validi.

Conclusione

Ora ricorda, la domanda riguardava un'unità NTFS esterna, cioè locale. Ciò significa che le regole che abbiamo appena osservato per le condivisioni di Samba potrebbero non essere applicabili qui.

A seconda del driver utilizzato per archiviare questi file (che potrebbe variare in base alla versione di Linux/macOS, ad esempio ntfs-3g o il driver di terze parti utilizzato, ad esempio il driver di Paragon), vedo le seguenti possibili cause rimaste dopo aver esaminato gli esperimenti precedenti:

  1. il nome del file conteneva un : , " o ? ... questo mi sembra il più probabile, dato che avevo accidentalmente copiato e incollato io stesso titoli di ebook, contenenti questi caratteri. Possiamo praticamente escludere / e gli altri caratteri "proibiti" sono almeno meno probabili.
  2. il lato Windows e macOS vede il nome non valido, prova a guardare il nome DOS 8.3, ma non ne è stato generato nessuno. Questo dipende in qualche modo dall'esatta versione di Windows e dalla sua configurazione e poiché non ho dispositivi macOS in giro, non posso nemmeno testare quello scenario. Inoltre, non sono sicuro se su un sistema Windows in cui i nomi 8.3 sono abilitati Windows andrebbe retroattivamente e genererebbe un nome 8.3 se, diciamo, il lato Linux saltasse quella parte. Perché se ricordo bene il driver NTFS decide se il rispettivo record ("attributo") viene popolato.
  3. la lunghezza del nome del percorso è stata superata. Penso che superare la lunghezza dei segmenti di percorso sia impossibile, perché NTFS non ti consente di memorizzare più di 255 valori a 16 bit per un segmento di percorso, ma anche la lunghezza complessiva del percorso potrebbe essere stata superata (vedi questo link).

Per il primo scenario, consiglierei di utilizzare fslint sul lato Linux per disinfettare i nomi dei file (e delle cartelle). Esistono altri strumenti simili e YMMV, fai una scelta.

Spero che sia di aiuto. Ci è voluto abbastanza tempo per mettere per iscritto i miei pensieri.

Ulteriori letture

  • Denominazione di file, percorsi e spazi dei nomi
  • La guida definitiva sulla conversione del percorso da Win32 a NT

Linux
  1. Come configurare il server SAMBA e trasferire file tra Linux e Windows

  2. Linux – Dopo l'arresto anomalo di Fs e l'esecuzione di Fsck, alcuni file sono stati recuperati ma non sono stati inseriti in Lost+found?

  3. Cosa sono i file /dev/zero e /dev/null in Linux

  4. In quali linguaggi sono scritti Windows, Mac OS X e Linux?

  5. Perché Windows non riconosce i file all'interno delle partizioni Linux?

Trova ed elimina il file più vecchio se ci sono più di X file in una directory in Linux

Impedisci la cancellazione o la modifica accidentale di file e cartelle in Linux

Come aprire file e cartelle come amministratore in Nautilus File Manager in Linux

Come nascondere cartelle e file in Linux usando un file di testo

Risparmia spazio comprimendo file e cartelle in Linux

Condivisione di file tra Linux Mint e Windows 10