Чи повинна змінна шляху до каталогу закінчуватися косою рисою?


85

При визначенні шляху до каталогу як змінної чи константи, чи повинен він закінчуватися кінцевою рисою? Що таке конвенція?

pwdв Unix показує ваш поточний каталог без кінцевої косої риски, тоді як вкладка "Повна" cd /var/www/apps/включає кінцеву риску, що залишило мене невпевненим.

Відповіді:


23

Я не включаю кінцеву скісну риску, коли, наприклад, визначаю каталог для зберігання файлів. Це тому, що я буду використовувати його як

$store_file = "$store_path/$file_id";

Я завжди додаю кінцеву скісну риску перед використанням змінної, яка повинна містити шлях до каталогу. Я думаю, що краще завжди додавати один, ніж гадати, чи включена кінцева коса риса.


29
Відсутність косої риски означає, що незрозуміло, чи шлях у $ store_path є файлом або каталогом. "/ tmp / store_data" це файл чи каталог?
Дарвін,

4
Використовуючи щось на зразок функції PHP realpath () , вона не друкує кінцеву скісну риску. Ваша система та інструменти можуть диктувати вашу конвенцію.
jmbertucci

10
Наявність декількох скісних рисок у будь-якому місці зазвичай трактується як одна коса риса. Отже, ви могли б навіть мати щось подібне, '///' + $root + '//' + $file + '/'і це не мало би значення. Хоча наявність кінцевої косої риси - це хороший спосіб визначити, чи є шлях файлом чи каталогом, було б краще додати до таких шляхів, '/' + $rootа не $root + '/'як ви не можете бути впевнені, що шлях, який додається, має кінцеву скісну риску , але ви можете бути відносно впевнені, що множинні похилі риси будуть інтерпретовані як одна коса риса в більшості середовищ.
Xtrinity

3
@MatthewSlyman, Моя думка полягала в тому, що всі очікують, що це /tmp/store_data/каталог, хоча незрозуміло, що такий самий шлях без косої риски/tmp/store_data
Дарвін,

6
Проблема в цьому: якщо змінної не існує, вона збігається з порожньою, і rm -rf $foo/$barможе закінчуватися наrm -rf /
12431234123412341234123

100

Я використовую кінцеву скісну риску, оскільки:

  1. "Якщо він закінчується косою рисою, це каталог. Якщо ні, це файл." це легкий запам’ятати.

  2. Принаймні в операційних системах, якими я зазвичай користуюся, подвоєння косої риси не викликає проблем, тоді як пропускання косої риси викликає великі. Отже, найбезпечніше вставити скісну риску у змінну та використовувати "$ path / $ file", коли використовується.


9
Шлях до каталогу можна відрізнити від шляху до файлу лише у тому випадку, якщо шлях до каталогу має косу риску.
Дарвін,

4
Кілька косих рисок еквівалентно одній косой рисі, якщо тільки шлях не починається з подвійної косої риски. Дивіться unix.stackexchange.com/questions/1910/…
jdh8

4
Додатково додавання скісної риски в кінці змінної дозволяє "$ path $ file" замість "$ path / $ file", що дозволяє пустий $ path - тобто поточний робочий каталог. Але ніколи не використовуйте зворотну скісну риску замість косої риски.
фантасторія

Дескриптори файлів теж корисні
Франческо Гуалацці

@ jdh8 Навіть якщо шлях починається з подвійних скісних рисок, він все одно повинен бути еквівалентний одній косою рисою. Хоча це може змінюватися від реалізації до реалізації. Стандарти unix стверджують, що 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.здебільшого було помічено, що подвійні скісні риски зазвичай трактуються як одна коса риса в загальних реалізаціях.
Xtrinity

12

Я знаю, що цьому 10 років, але я хотів вкласти свої дуже самовпевнені 0,02 долара.

Ні. Зовсім ні.

Мова йде про систему Unix. Щодо самого каталогу, це вузол, як і будь-який інший. При зверненні до каталогу, він не повинен коли - або неекрановані слеш в назві (посилання: dirname, pwd, ~, echo $HOME, echo $PATH, вихід з lsін).

При згадці вмісту каталогів, то вам потрібен слеш. Тобто це ls /home/karl/доречніше ніж ls /home/karl(FTR, я майже завжди роблю останнє, тому що ... ну, лінивий).

Використовуючи змінну, що містить каталог, для створення повного шляху до файлу, ви завжди очікуєте включити скісну риску (тобто, e:) cp ${HOME}/test ${OTHER_DIR}/.

Як очікується , що каталог не закінчується косою рисою. Будь-яке очікування того, що каталог закінчується косою рисою, є помилковим. Таким чином, додаючи скісну риску до кінця символу*_DIR змінної буде підривати очікування.

Що стосується заповнення вкладки, тут передбачається, що ви заходите в цей каталог. Таким чином, допомога, яку надає заповнення вкладки, полягає у тому, щоб ви потрапили до цього каталогу, щоб ви могли зробити наступний вибір на основі його вмісту.

(посилання з коментарів: Заблудження Filepath , зі Talk:Path_(computing)сторінки Вікіпедії . Дякую, Джон cj )

Варто зазначити, що те, що це неправильно, не означає, що інструменти / пакети / бібліотеки цього ніколи не роблять. Дуже поширене явище, коли такі речі додають кінцеву скісну риску, коли такої не повинно бути. Тому, як пропонували Беван та Пол Ф , під час використання сторонніх інструментів найкраще видалити всі кінцеві слєші, які можуть існувати в іменах каталогів.

Unix Inodes

Inode (індексний вузол) - це структура даних у файловій системі стилю Unix, яка описує об'єкт файлової системи, такий як файл або каталог.

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

Стандарт ієрархії файлової системи

Стандарт для Unix файлової системи (Filesystem Hierarchy Standard, AKA FHS) ясно показує , що каталоги мислиться як має слеш, а скоріше вміст каталогу починається з косим риси (єдиний виняток з цього правила, /тому що ми не будемо називати корінь файлової системи, використовуючи порожній рядок ... і ніколи не слід створювати там файли.)

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

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


Відмінна відповідь. Я схильний використовувати цей підхід, але ніколи не був повністю повним щодо своїх міркувань, чому. Це єдина відповідь, яка це прибиває.
wardw

4
Це корінь, /який порушує шаблон. І якщо б ви почали свої міркування звідси (рекурсивно), ви можете дійти до суперечностей, які можуть бути в основі розбіжних практик (про що свідчать відповіді тут). Але як тільки ви приймаєте це як виняток, тоді все інше впадає в чергу.
wardw

Розумію. Трохи погрався з іменем. Якщо ви маєте намір явно зберігати каталог у шляху, завершіть шлях знаком «/.», Де крапка представляє поточний каталог.
TamusJRoyce

Ви ніколи не закінчите а /., це просто жахлива ідея; крім того, що він вводить дуже незвичний вміст, що призводить до несподіваних проблем, він виглядає просто безглуздо.
Karl Wilbur

2
@wardw ви можете вважати, що кореневий каталог називається порожнім рядком, тоді як "/" - це порожній рядок, за яким стоїть коса риса і означає "вміст кореневого каталогу".
bobpaul

9

Так, це повинно бути, як:

Pathname + filename = повністю кваліфіковане розташування файлу.

ТОЖ, скісна риска між останнім каталогом та іменем файлу повинна бути або в кінці імені шляху, або на початку імені файлу. Префікс імен файлів за допомогою / означає, що вам потрібно це врахувати, якщо ви просто хочете відкрити файл (тобто якщо ви припускаєте, що некваліфіковане ім'я файлу є в поточному робочому каталозі).


5
.. а якщо не взяти його до уваги, ви, можливо, ненавмисно возитесь з /, і таким чином лежить божевілля
JustJeff

5

Кожного разу, коли я зберігаю шляхи до каталогів або повертаю їх з API, я намагаюся дотримуватись правила дотримання кінцевої риски. Це дозволяє уникнути загальної неоднозначності "це файл чи каталог".

Додаток :
Це не задумано замінити використання методів, які можуть допустити або кінцеву скісну риску, або її відсутність. Навіть використовуючи цю конвенцію, я все одно завжди використовую Path.Combine(...)подібні методи.


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

5

Можливо, вам слід подумати, що ваше рішення буде означати для файлів. Якщо ви не включите кінцеву скісну риску в кінці імені каталогу, вам доведеться додати її до початку імені файлу .

Тепер, якщо з якихось причин шлях, що веде до файлу, відсутній, коли ви об'єднуєте рядки, ви отримуєте щось подібне, /filenameяке є не просто файлом, а абсолютним шляхом з кореневого каталогу (де б це не було в цьому контексті) .

Тому я закінчую свої шляхи косою рисою і зберігаю файли як файли.


1
Альтернативою тут є вираз вашого імені файлу як ./filename. Але загалом це повинен бути відповідальність коду, що об'єднує шляхи, щоб зробити це належним чином - і не робити припущення в будь-якому випадку.
вартовий

4

Я знаю, що це стара тема, але я думав поділитися тим, що роблю. Якщо це можливо, я зазвичай дозволяю обидва і роблю щось подібне (якщо це був PHP):

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

Таким чином, якщо каталог визначено у конфігураційному файлі, не має значення, чи буде наступна людина, яка його змінить, включати кінцеву скісну риску чи ні.


4

У php функція dirname (__ FILE __) повертає ім'я каталогу без скісної риски в кінці. Я схильний дотримуватися цієї конвенції.

В іншому випадку використання косої риски в кінці імені каталогу конфліктуватиме з тим, як працює dirname (..), і тоді ви застрягли в обробці двох випадків, оскільки ви не знаєте, чи походить назва каталогу від dirname (.. ) функція або вміст, визначений кінцевою рискою.

Підсумок: Не використовуйте кінцеву скісну риску, оскільки dirname (..) цього не робить.

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

Для інших мов перевірте функцію, яка витягує назву шляху, і переконайтеся, що вона використовує кінцеву скісну риску чи ні, а потім дотримуйтесь угоди мови.


2
Виняток: dirname ('/ test') = '/' - замість повернення порожнього рядка, dirname у цьому випадку повертає одну косу риску! Дивіться примітки тут .
Метью Слайман,

3

Я схильний просто додавати кінцеву скісну риску, оскільки я, швидше за все, буду використовувати цей каталог для додавання / отримання файлів ...

Що стосується веб-посилань, це може насправді підвищити продуктивність, залишаючи кінцеву скісну риску

http://www.netmechanic.com/news/vol4/load_no11.htm


2

Так, існує безліч файлових систем, які підтримують файли без будь-яких розширень, тому завжди додавайте кінцеву скісну риску, щоб уникнути проблем.


1

Я ніколи не бачив твердої конвенції в будь-якому випадку.

Правда впевнений, що незалежно від того, на що ви погодитесь, хтось інший буде на 100% впевнений, що це має бути по-іншому. Отже, найкраща ідея - терпіти, щоб все було встановлено в будь-якому випадку.

У світі .NET Path.Combine () надає вам спосіб вирішити це - в інших середовищах існують еквіваленти, починаючи з файлів cmd і вище.


1

Я думаю, це один із тих рідкісних випадків, коли правильна теоретична та практична відповідь відрізняється.

Здається, відповідь @Karl Wilbur напевно є правильною в теоретичному розумінні, оскільки ви повинні мати можливість відрізнити посилання на сам вузол каталогу від вмісту каталогу.

Але на практиці я буду стверджувати, що правильна відповідь протилежна:

  • Найголовніша причина - ви можете з упевненістю сказати, що шлях /home/FSObjectX/є папкою, тоді /home/FSObjectXяк неоднозначний. Ніхто не може сказати, чи це файл папки.
    Специфікації завжди повинні бути точними та однозначними, коли це можливо.

  • У переважній більшості випадків ви завжди будете посилатися на вміст папки, а не на сам вузол директорії.
    У тих рідкісних випадках, коли ви насправді це робите, це легко можна обробити в коді, видаливши будь-який додатковий кінцевий розділювач директорій.

  • Використання подвійних роздільників не завдасть шкоди, хоча відсутність такого точно буде.
    Теоретично поганий аргумент, оскільки ви не повинні кодувати випадково, але на практиці трапляються помилки, і, можливо, використання кінцевого dir-sep може закінчитися кількома помилками часу виконання у кінцевого користувача.

Читаючи цю цікаву тему, я не знайшов жодних недоліків використання кінцевого dir-sep, лише те, що це неправильно в теоретичному розумінні. Або я щось пропустив?


на практиці ви виявите, що правильним очікуванням є не містити кінцеву скісну риску. Просто подивіться на кожен використовуваний вами інструмент, який був написаний компетентними розробниками.
Карл Вілбур,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.