In che modo Linux gestisce più separatori di percorsi consecutivi (/ home //// nome utente /// file)?


111

Sto lavorando a uno script Python che passa i percorsi dei file a un sottoprocesso scp. Va tutto bene, ma mi trovo in una situazione in cui potrei finire per concatenare un percorso con un nome file tale che ci sia un doppio " /nel percorso. So che a bash non importa se hai più separatori di file, ma mi chiedo come sia corretto. È bash che spoglia di più /o davvero non importa mai?

Chiedo perché mi salverà diverse righe di codice per verificare se sono presenti ulteriori messaggi /concatenati. So che non è un grosso problema, ma sono anche curioso. Ho uno script bash che ha la linea cd //usr(anziché cd /usr), il che sembra implicare che potrebbe esserci un significato nell'uso di più /s in un percorso


7
Investirei nelle righe extra del codice ...
Stefan,

5
Nel caso in cui qualcuno se ne frega, cosa che di certo non fa a nessuno, in realtà ho fatto uso di Python joine di abspathcomandi simili.
Falmarri,

Risposte:


165

Sono consentite più barre e equivalgono a una singola barra. Dalla specifica Single Unix (versione 3) , definizioni di base §3.266 nome percorso : "Molte barre successive sono considerate uguali a una barra".

C'è un'eccezione: se un percorso inizia esattamente con due barre, può essere trattato in modo diverso (rif: definizioni base §4.11 risoluzione percorso ). Linux stesso non lo fa, anche se alcune applicazioni potrebbero farlo e altri sistemi unix-ish (ad esempio Cygwin).

Un finale /alla fine di un percorso obbliga il percorso a fare riferimento a una directory. Nelle definizioni di base ( POSIX 1003.1-2001 (Single Unix v3) §4.11 risoluzione percorso , un trailing /equivale a un trailing /.. Le definizioni di base POSIX 1003.1-2008 (Single Unix v4) §4.12 rimuovono il requisito per renderlo equivalente /., al fine per far fronte a directory inesistenti (ad esempio, mkdir foo/è necessario per funzionare, mentre mkdir foo/.non dovrebbe - vedere la logica del cambiamento).

Per i programmi che agiscono su una voce della directory, se fooè un collegamento simbolico a una directory, il passaggio foo/è un modo per far sì che il programma agisca sulla directory anziché sul collegamento simbolico.

¹ Notare che ciò vale solo per la risoluzione del nome percorso, ovvero quando si accede ai file. Le manipolazioni del nome file potrebbero funzionare in modo diverso. Per esempio basenamee dirnameignorare slash.


7
L'equivalente /.è stato rimosso dopo un successivo processo di discussione in quanto ambiguo. Ad ogni modo +1 per trovare questo tipo di informazioni ben riassunte è difficile.
Hakre,

17

Anche il sistema operativo non sembra preoccuparsene, avendo appena provato un programma C con una scala di sistema diretta da aprire con un // nel percorso.

Puoi usare la funzione di libreria python os.path.normpath per normalizzarlo però, il che ti evita di scansionare la stringa in cerca di extra. Altre lingue hanno funzioni simili.

http://docs.python.org/library/os.path.html#os.path.normpath


5
Fai attenzione al seguente commento nella fonte di normpath: Normalizza un percorso, ad esempio A // B, A /./ B e A / foo /../ B diventano tutti A / B. Dovrebbe essere chiaro che questo può cambiare il significato del percorso se contiene collegamenti simbolici!
Bluehorn,

8

Su tutti i sistemi Unix che ho visto è lo stesso di un singolo /, ma lo standard Unix lo specifica

Un nome di percorso che inizia con due barre successive può essere interpretato in modo definito dall'implementazione, anche se più di due barre iniziali devono essere trattate come una barra singola.

quindi può essere gestito appositamente, a seconda del sistema. (Alcune versioni precedenti di Unix utilizzavano un doppio vantaggio /per l'accesso al filesystem remoto e potrebbero essercene ancora alcune.)


7
Cygwin (anche se non un vero UNIX) si traduce //remote/...in accesso al filesystem remoto, probabilmente per coerenza con Windows ' \\remote\....
effimero

2
Credo (ma non riesco a trovare un buon riferimento in questo momento) che le API compatibili con POSIX di Windows tratteranno anche //remote/...lo stesso \\remote\...formato del percorso UNC .
Stephen P,

1
Penso di ricordare che i percorsi portatili di Boost.Filesystem gestiscono //in modo speciale, in quanto possono essere testati falsecome assoluti, conformi alle specifiche Unix / POSIX.

7

Usa os.path.joinin Python e non otterrai più barre. Costruire i nomi dei file concatenando le stringhe è considerato un povero stile Python.


Sono d'accordo, ma il nome file fa parte di una stringa di comando e invece di analizzare la stringa di comando da aggiungere al nome del file (alla fine), vorrei solo aggiungerlo.
Falmarri,

1
@Falmarri: non puoi semplicemente aggiungere un nome file a una stringa di comando! Una stringa di comando verrà analizzata dalla shell, quindi è necessario citare i caratteri speciali nei nomi dei file. Quindi è necessario costruire il nome del file, quindi citarlo correttamente per inserirlo nella stringa di comando.
Gilles,

Questo è un progetto davvero specifico che sto per usare solo me stesso. Probabilmente non sono stato abbastanza chiaro da giustificare di non essere solido su questo. Ricevo questa stringa di percorso di file da una classe che mi dà un percorso di file con escape corretto e così via. E lo sto aggiungendo a un argomento della riga di comando
Falmarri,

1
@Falmarri: Quindi usa normpath per ripulire il valore della riga di comando che non controlli, quindi usa join per metterli insieme.
Neil Mayhew,

Questo è in realtà quello che ho finito per fare = \ Non sono riuscito a gestire il caso speciale in cui mi è stato dato /molto bene.
Falmarri,

3

Non c'è differenza.

Le barre multiple vengono ignorate (senza effetto), ad esempio:

ls -al //usr///////bin/sed

7
Ci può essere se sono esattamente due e all'inizio; Un percorso che inizia con due barre successive può essere interpretato in modo definito dall'implementazione . In pratica penso che sia giusto e vengono semplicemente ignorati
Michael Mrozek

Grazie Chris, apprezzo il chiarimento! (sfortunatamente il login OpenID non funziona per me o vorrei votarti)

@Rob Non sei registrato, ma hai ancora effettuato l'accesso (sei monitorato dal tuo cookie). Dovresti essere in grado di registrarti ora per connettere un OpenID al tuo account, ma dovresti essere in grado di votare in entrambi i modi
Michael Mrozek

Grazie Michael ma "devi effettuare l'accesso o registrarti per votare". Quando usi solo un indirizzo e-mail e un nome non hai i privilegi completi. E poiché OpenID sta scadendo e non ho voglia di creare un altro account, sono sfortunato. Immagino sia colpa mia se sono pigro, ma apprezzo l'aiuto.

0

Ovviamente puoi normalizzare un percorso con possibili multipli / (barre) passandoci attraverso tr -s

NORMALIZED=$(echo "$UNHYGIENIC" | tr -s / /)

... e poi usa $NORMALIZED

Tuttavia, dovrebbe essere necessario. Per quanto ne so, qualsiasi kernel UNIX dovrebbe ignorare i separatori di percorsi simultanei --- o trattarli concettualmente come ... /./...


"should" -> "shouldn't".
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.