Una variabile del percorso di una directory dovrebbe terminare con una barra finale?


89

Quando si definisce un percorso a una directory come variabile o costante, dovrebbe terminare con una barra finale? Qual è la convenzione?

pwdin Unix mostra la tua directory corrente senza una barra finale, mentre la scheda completa di cd /var/www/apps/include la barra finale, il che mi ha lasciato incerto.

Risposte:


24

Non includo la barra finale quando, ad esempio, definisco una directory per la memorizzazione dei file. Questo perché lo userò così

$store_file = "$store_path/$file_id";

Aggiungerò sempre una barra finale prima di utilizzare una variabile che dovrebbe contenere un percorso di directory. Penso che sia meglio aggiungerne sempre uno piuttosto che chiedersi se la barra finale è inclusa.


29
Non avere una barra finale significa che non è chiaro se il percorso in $ store_path è un file o una directory. "/ tmp / store_data" è un file o una directory?
Darwin

4
Quando si usa qualcosa come la funzione realpath () di PHP , non stamperà la barra finale. Il tuo sistema e gli strumenti potrebbero dettare la tua convenzione.
jmbertucci

10
La presenza di più barre in un punto qualsiasi di solito viene interpretata come una singola barra. Quindi potresti anche avere qualcosa di simile '///' + $root + '//' + $file + '/'e non avrebbe importanza. Sebbene avere la barra finale sia un buon modo per discernere se il percorsoèun file o una directory sarebbe meglio aggiungere a percorsi come '/' + $rootpiuttosto che $root + '/'come non puoi essere sicuro che il percorso a cui viene aggiunto abbia una barra finale , ma puoi essere relativamente certo che più barre verranno interpretate come una singola barra nella maggior parte degli ambienti.
Xtrinity

3
@MatthewSlyman, il punto era che tutti si aspettano che questa /tmp/store_data/sia una directory, mentre non è chiaro quale sia lo stesso percorso senza una barra traling/tmp/store_data
Darwin

6
Il problema con questo è: se una variabile non esiste, è uguale a vuota e rm -rf $foo/$barpuò terminare conrm -rf /
12431234123412341234123

102

Vado con la barra finale perché:

  1. "Se finisce con una barra, è una directory. In caso contrario, è un file." è una convenzione facile da ricordare.

  2. Almeno sui sistemi operativi che uso comunemente, raddoppiare la barra non causa problemi, mentre omettere la barra ne provoca di grandi. Pertanto, è più sicuro mettere la barra nella variabile e utilizzare "$ path / $ file" quando lo si utilizza.


9
Un percorso di directory è distinguibile da un percorso di file solo se il percorso di directory ha una barra finale.
Darwin

4
Più barre sono equivalenti a una barra, a meno che il percorso non inizi con una doppia barra. Vedi unix.stackexchange.com/questions/1910/…
jdh8

4
Inoltre l'aggiunta di una barra alla fine di variabile consente "$ path $ file" invece di "$ path / $ file", che consente $ path vuoto, ovvero la directory di lavoro corrente. Ma non usare mai la barra rovesciata invece di quella barra.
fantastory

Utili anche i descrittori dei file
Francesco Gualazzi

@ jdh8 Anche se il percorso inizia con doppie barre, dovrebbe comunque essere equivalente a una barra. Anche se questo può cambiare da implementazione a implementazione. Gli standard unix affermano che A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.per la maggior parte è stato osservato che le doppie barre di solito vengono interpretate come una singola barra nelle implementazioni comuni.
Xtrinity

14

So che questo ha 10 anni, ma volevo aggiungere i miei $ 0,02 molto supponenti.

No. No. Assolutamente no.

Stiamo parlando di un sistema Unix. In riferimento alla directory stessa, è un nodo come un altro. Quando si fa riferimento alla directory, non dovrebbe mai avere una barra senza caratteri di escape nel suo nome (ref: dirname, pwd, ~, echo $HOME, echo $PATH, l'output dils , et al).

Quando si fa riferimento al contenuto di una directory, allora avete bisogno di una barra. Vale a dire, ls /home/karl/è più appropriato dils /home/karl (FTR, faccio quasi sempre quest'ultimo perché ... beh, pigro).

Quando si utilizza una variabile contenente una directory per creare il percorso completo di un file, ci si aspetterebbe sempre di includere la barra (i., E: cp ${HOME}/test ${OTHER_DIR}/ .

È previsto che una directory non finisca con una barra. Qualsiasi aspettativa che una directory finisca con una barra è sbagliata. Quindi l'aggiunta di una barra alla fine del *_DIRvalore di una variabile sovvertirebbe le aspettative.

Per quanto riguarda il completamento della scheda, l'aspettativa qui è che tu stia andando in quella directory. Pertanto, l'assistenza fornita dal completamento con tabulazione è di portarti in quella directory in modo che tu possa fare la scelta successiva in base al suo contenuto.

(riferimento dai commenti: Idee sbagliate sul percorso del file , dalla Talk:Path_(computing)pagina di Wikipedia . Grazie, john cj )

Vale la pena notare che solo perché è sbagliato non significa che strumenti / pacchetti / librerie non lo facciano mai. È un evento fin troppo comune che cose del genere aggiungano una barra finale quando non dovrebbe esistere. Pertanto, come suggerito da Bevan e Paul F , quando si utilizzano strumenti di terze parti, è meglio rimuovere eventuali barre finali che potrebbero esistere nei nomi delle directory.

Unix Inodes

L'inode (nodo indice) è una struttura di dati in un file system in stile Unix che descrive un oggetto file system come un file o una directory.

- https://en.wikipedia.org/wiki/Inode

Standard della gerarchia del file system

Lo standard per il filesystem Unix (il Filesystem Hierarchy Standard, AKA FHS) mostra chiaramente che le directory non sono pensate come aventi una barra finale, ma piuttosto il contenuto della directory inizia con una barra (l'unica eccezione a questo è/ perché non faremo riferimento a la radice del filesystem usando una stringa vuota ... e non si dovrebbero mai creare file lì comunque.)

- http://www.pathname.com/fhs/pub/fhs-2.3.html

- https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard


Ottima risposta. Ho teso a usare questo approccio, ma non sono mai stato del tutto completo per quanto riguarda il perché. Questa è l'unica risposta che lo inchioda.
reparto

4
È la radice /che rompe lo schema. E se dovessi iniziare il tuo ragionamento da qui (in modo ricorsivo) puoi quindi arrivare alle contraddizioni che possono essere alla base delle pratiche divergenti (come evidenziato dalle risposte qui). Ma una volta che lo accetti come eccezione, tutto il resto è in linea.
reparto

Vedo. Ho giocato un po 'con dirname. Se si intende memorizzare esplicitamente una directory in un percorso, terminare il percorso con "/.", Dove il punto rappresenta la directory corrente.
TamusJRoyce

2
@wardw potresti pensare alla directory root come a una stringa vuota, mentre "/" è una stringa vuota seguita da una barra e significa "il contenuto della directory root".
bobpaul

1
Questa risposta dovrebbe essere votata di più. Vedi anche la sezione Idee sbagliate sul percorso del file nel Wiki.
john cj

9

Sì, dovrebbe, come:

Pathname + filename = percorso file completo.

Quindi la barra tra l'ultima directory e il nome del file deve essere alla fine del percorso o all'inizio del nome del file. Prefissare i nomi dei file con / significa che è necessario tenerne conto se si desidera solo aprire un file (cioè se si presume che un nome di file non qualificato sia nella directory di lavoro corrente).


5
.. e non tenerne conto significa che potresti inavvertitamente scherzare con /, e in questo modo la follia sta
JustJeff

5

Ogni volta che memorizzo i percorsi delle directory o li restituisco dalle API, cerco di attenermi alla convenzione di mantenere una barra finale. Ciò evita l'intera ambiguità "è un file o una directory".

Addendum :
non intende sostituire l'utilizzo di metodi che possono tollerare una barra finale o la sua assenza. Anche usando questa convenzione uso sempre Path.Combine(...)metodi simili.


python:os.path.join(dir, subdir_or_file)
IceArdor

5

Forse dovresti pensare a cosa significherebbe la tua decisione per i file. Se non includi la barra finale alla fine del nome di una directory, dovrai aggiungerla all'inizio del nome del file .

Ora, se per qualche motivo, il percorso che porta al file manca quando concatenate le stringhe, vi ritroverete con qualcosa di simile /filename che non è solo un file ma un percorso assoluto dalla directory principale (ovunque sia in quel contesto) .

Ecco perché chiudo i miei percorsi con una barra e conservo i file come file.


1
L'alternativa qui è esprimere il nome del file come ./filename. Ma in generale dovrebbe essere responsabilità del codice concatenare i percorsi per farlo correttamente e non fare ipotesi in entrambi i casi.
reparto

4

So che questo è un vecchio thread ma ho pensato di condividere quello che faccio. Se possibile, normalmente consentirei entrambi e farei qualcosa del genere (se fosse PHP):

$fullPath = rtrim($directory, '/') . '/filename.txt');

In questo modo, se la directory è definita in un file di configurazione, non importa se la persona successiva a modificarla include la barra finale o meno.


4

In php, poiché la funzione dirname (__ FILE __) restituisce il nome della directory senza una barra alla fine. Tendo ad attenermi a quella convenzione.

Altrimenti, l'uso di una barra alla fine del nome di una directory entrerà in conflitto con il modo in cui funziona dirname (..) e quindi sarai bloccato con la gestione dei due casi poiché non sai se il nome della directory proviene da un dirname (.. ) o un contenuto definito con una barra finale.

Conclusione: non utilizzare una barra finale poiché dirname (..) non lo fa.

// PHP Example
dirname(__FILE__); // returns c:\my\directory without a trailing slash, so stick to it!

Per altre lingue, controlla la funzione che estrae un percorso e verifica se sta utilizzando una barra finale o meno, quindi attieniti alla convenzione della lingua.


2
Un'eccezione: dirname ('/ test') = '/' - invece di restituire una stringa vuota, dirname restituisce una singola barra in questo caso! Vedi le note qui .
Matthew Slyman


2

Sì, ci sono molti filesystem che supportano file senza alcuna estensione, quindi aggiungi sempre la barra finale per evitare problemi.


1

Non ho mai visto una convenzione ferma in entrambi i casi.

Abbastanza sicuro, però, che qualunque cosa tu decida, qualcun altro sarà sicuro al 100% che dovrebbe essere il contrario. Quindi, l'idea migliore è tollerare che le cose vengano impostate in entrambi i modi.

Nel mondo .NET, Path.Combine () ti dà un modo per gestirlo: ci sono equivalenti in altri ambienti, dai file cmd in su.


1

Immagino che questo sia uno di quei rari casi in cui la risposta teorica e pratica corretta è diversa.

Sembra che la risposta di @Karl Wilbur sia sicuramente corretta in senso teorico, poiché dovresti essere in grado di distinguere un riferimento al nodo della directory stesso dal contenuto della directory.

Ma in pratica sosterrò che la risposta corretta è l'opposto:

  • Il motivo più importante è che puoi dire con certezza che il percorso /home/FSObjectX/è una cartella, mentre /home/FSObjectXè ambiguo. Nessuno può dire se questo è un file di cartella.
    Le specifiche devono essere sempre precise e univoche quando possibile.

  • Nella stragrande maggioranza dei casi, farai sempre riferimento al contenuto di una cartella, non al nodo dir stesso.
    In quei rari casi in cui lo fai effettivamente, può essere facilmente gestito nel codice rimuovendo qualsiasi separatore di directory finale opzionale.

  • L'uso di doppi separatori di directory non farà alcun danno, anche se mancarne uno lo farà sicuramente.
    In teoria un pessimo argomento in quanto non dovresti programmare per "caso", ma in pratica si verificano errori e forse l'uso di dir-sep finale potrebbe finire con un minor numero di errori di runtime per un utente finale.

Leggendo questo interessante thread non ho riscontrato alcuno svantaggio nell'usare trailing dir-sep, solo che è sbagliato in senso teorico. O mi sono perso qualcosa?


in pratica scoprirai che l'aspettativa corretta non è quella di contenere una barra finale. Basta guardare ogni strumento che usi che è stato scritto da sviluppatori competenti.
Karl Wilbur
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.