È ansible utilizzare “/” in un nome file?

So che questo non è qualcosa che dovrebbe mai essere fatto, ma c’è un modo per usare il carattere barra che normalmente separa le directory all’interno di un nome file in Linux?

La risposta è che non puoi, a meno che il tuo filesystem non abbia un bug. Ecco perché:

C’è una chiamata di sistema per rinominare il file definito in fs/namei.c chiamato renameat :

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

Quando viene richiamata la chiamata di sistema, esegue una ricerca del percorso ( do_path_lookup ) sul nome. Continua a tracciare questo, e arriviamo a link_path_walk che ha questo:

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

Questo codice si applica a qualsiasi file system. Cosa significa questo? Significa che se si tenta di passare un parametro con un carattere '/' effettivo come nome del file utilizzando i metodi tradizionali, non farà ciò che si desidera. Non c’è modo di sfuggire al personaggio. Se un filesystem “supporta” questo, è perché entrambi:

  • Usa un carattere unicode o qualcosa che assomiglia a una barra ma non lo è.
  • Hanno un bug.

Inoltre, se si entra e si modificano i byte per aggiungere un carattere barra in un nome file, accadono cose brutte. Questo perché non si può mai fare riferimento a questo file per nome 🙁 dal momento in cui lo si è fatto, Linux assumerebbe che si stesse riferendo a una directory inesistente. L’uso della tecnica ‘rm *’ non avrebbe funzionato, dal momento che bash lo espande semplicemente al nome file. Anche rm -rf non funzionerebbe, dal momento che un semplice strascico rivela come vanno le cose sotto il cofano (accorciate):

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

Si noti che queste chiamate a unlinkat falliscono perché devono fare riferimento ai file per nome.

Potresti usare un carattere Unicode che appare come “/” (ad esempio questo glifo apparentemente ridondante ) assumendo che il tuo filesystem lo supporti.

Solo con una codifica concordata. Ad esempio, potresti essere d’accordo che % sarà codificato come %% e che %2F significherà un / . Tutto il software che ha avuto accesso a questo file dovrebbe comprendere la codifica.

Dipende da quale filesystem stai usando. Di alcuni dei più popolari:

  • ext3: no
  • ext4: no
  • jfs: Sì
  • reiserfs: no
  • xfs: no

In generale è una ctriggers idea cercare di usare caratteri “cattivi” in un nome di file; anche se in qualche modo lo gestisci, tende a rendere difficile l’uso del file in un secondo momento. Il separatore del filesystem non funziona affatto, quindi dovrai scegliere un metodo alternativo.

Hai preso in considerazione la codifica URL dell’URL, quindi l’hai utilizzata come nome file? Il risultato dovrebbe essere corretto come nome file ed è facile ribuild il nome dalla versione codificata.

Un’altra opzione è creare un indice – creare il nome file di output usando il metodo che preferisci – nomi numerati in sequenza, hash SHA1, qualunque cosa – quindi scrivi un file con la coppia di nomi file / URL generata. Puoi salvarlo in un hash e usarlo per eseguire una ricerca da URL a nome file o viceversa con la versione invertita dell’hash, e puoi scriverlo e ricaricarlo in seguito, se necessario.

La risposta breve è: No, non puoi. È un divieto necessario a causa di come viene definita la struttura della directory.

E, come accennato, puoi visualizzare un carattere unicode che sembra “una barra”, ma questo è quanto puoi.