Slash и backslash: вехи на пути

Немного истории


Slash

Возникновение слеша относят к временам Римской империи. На ранних стадиях современности, во Фрактуре [1], которая была широко распространена по всей Европе в средневековье, слеш (/) использовался вместо запятой, в то время как двойной слеш (//) использовался вместо тире. Двойной слеш, в конечном счете, превратился в символ похожий на знак равенства (=), а позже был еще больше упрощен до тире или дефиса [2].

Backslash

Боб Бемер ввел обратный слеш (\) в набор символов ASCII, 18 сентября 1961 года, как результат изучения частоты использования символов встречающихся в частности в программах на ALGOL’е. Тогда же вместе с обратным слешем в стандарт были включены и квадратные скобки.
В частности \ был введен, чтобы булевы операторы ALGOL’a AND и OR могли быть представлены с помощью ASCII символов как "/\" и "\/" соответственно [3,4].
Как же вышло, что исторически православный слеш заменился на свое зеркальное отображение, введенное как вспомогательный символ специально для уже мертвого языка?

Русскоязычная Википедия по этому говорит вот что:
В операционных системах DOS и Windows фирмы Microsoft и их аналогах других разработчиков, обратная косая используется для разделений имён директорий (каталогов) при указании пути к файлу. Прямая косая, применяемая для этого в Unix не могла быть использована в MS-DOS, потому что уже была задействована для указания ключей командной строки (оставшегося в наследство от СР/M, где MS-DOS команда «dir /w» писалась как «dir/w») [5].

Так как такое объяснение меня не слишком удовлетворило, пришлось найти статью «Why is the DOS path character "\"?» [6], которая вполне утолила моё любопытство. Вольный перевод избранных частей в моем исполнении:
То что символ "/" конфликтовал с разделителем пути другой относительно популярной ОС не был связан напрямую с разработчиками – в конце концов, DOS не поддерживал директорий, просто файлы в одном корневом каталоге.
Для MS-DOS 2.0 (в котором появился поддержка каталогов), дизайнеры DOSа выбрали гибридную версию – у них уже были имена дисков в наследство от DOS 1.0, поэтому разработчикам пришлось их использовать. И в дополнение к именам дисков они решили использовать *nix-style метод определения иерархии каталогов — вместо использования каталога в имени файла (как это было сделано в VMS и DEC-20), они просто сделали каталог и имя файла неотъемлемыми частями пути. Но с этим была проблема. Невозможно было использовать разделитель пути *nix (/), по той причине что слэш уже использовался как разделитель ключей.
Что им было делать? Они конечно могли использовать "." как в DEC, но точка уже использовалась как разделитель между именем файла и расширением. Поэтому они выбрали наилучший вариант из оставшихся — символ "\", который был визуально похож на "/".Таким вот образом и был выбран символ "\" для разделения путей в DOS.
Кстати есть небольшой секрет про MS-DOS. Разработчики DOS не были довольны таким положением дел – они использовали Xenix [7] для почты и прочих вещей, поэтому они были знакомы со структурой *nix команд. Поэтому они добавили в ОС возможность принимать в качестве разделителя путей как "/" так и "\" (это работает и сегодня, кстати – попробуйте выполнить «notepad c:/boot.ini» под XP (если ваш пользователь имеет права админа)). Дальше — больше. Они добавили недокументированный системный вызов, чтобы изменить символ разделителя ключей. И обновили утилиты, чтобы те поддерживали этот флаг. Они даже добавили в config.sys параметр, SWITCHAR, который позволит пользователю установить разделитель ключей на "-". Таким образом можно было превратить MS-DOS в *nix-style ОС, используя "-switch", и пути с разделителем "/".


Собственно к чему это все?


Меня побудила разобраться в этой теме следующая ситуация.
Была поставлена задача — наладить систему отчетов для автоматизированных тестов. Тесты у нас используются двух видов – Selenium (функциональные) и Jmeter (нагрузочные). Собственно в этом не было ничего сложного — для этих целей существует вполне себе open-source проект под названием logging selenium [8] и plugin для maven — chronos [9]. Настроив всё и протестировав отчеты локально, принялся за интеграцию с нашей CI — TeamCity. Вот тут-то меня и ждала та самая неожиданность, которая стала поводом для написания этой статьи.
После выполнения всех тестов отчет о Selenium-тестах имел следующий вид:

image

Всё отлично отображалось, и никаких отличий от локальной версии не было.
Но вот отчет, который отобразился для Jmeter-тестов, воодушевления не вызывал:

image
Напрочь отсутствовали все изображения на странице.
После просмотра исходного кода страницы стало понятно, что во всем виноват backslash. Ссылки на изображения были указаны в таком формате:

<img src="images\gc-performancetest.png">

Справедливости ради стоит заметить, что изображения отсутствовали в Firefox, но прекрасно отображались в IE. Хотя если бы IE не отображал ресурсы в URI которых встречается обратный слеш, как разделитель пути для Windows, то в, и не без того подпорченной, репутации индийских программистов образовалась бы еще одна брешь.

В общем, после недолгих раздумий стало понятно, что где-то внутри chronos'a используется File.separator, который и повинен в появлении обратного слеша в путях ресурсов и проблемах с отображением графиков в отчетах. Скачивание исходников плагина и исправление соответствующей строки, в которой формировался URL, решило проблему и дало возможность насладится прекрасными графиками, которые генерируются на основе результатов выполнения JMeter-тестов.

image
image

В заключении хотелось бы предостеречь от бездумного использования нативного File.separator – это не всегда приводит к кроссплатформенности, а в некоторых случаях даже может стать причиной появления новых багов. Обычный же слеш работает в Windows (зачастую), работает в *nix, Java и наконец его стоит уважать хотя бы по праву старшинства, так как он на полторы тысячи лет старше своего зазеркального брата.

P.S.: Спасибо хабраюзеру AlexanderYastrebov за внесение ясности относительно истории создания C.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 18

    +8
    Извините, не сдержался.
      +2
      простите, а что это?
        +5
        Видимо, уважаемый gaelpa намекает, что замазывать надо или качественнее, или не замазывать вообще.
          +2
          Обязательно учту, если в ближайшее время не выгонят :)
      0
      18 сентября — Backslash day!
      Этот год юбилейный.
        0
        хм… а каковы границы применимости слэша в виндах?
          0
          Насколько я понимаю у windows как таковых ограничений нету, но неизвестно как будут реагировать сторонние программы. Ворд например сохраняет файлы в пути которых используется слеш, а вот акробат ридер 9-ый отказывается.
            +1
            тоесть само winapi слэшнейтрально, а проблема только в отдельных альтернативно-ориентированных разработчиках, которые его не юзают?
          0
          (тут остроумный комментарий про jpeg vs png)

          Кстати, в MacOS, до перехода на юниксовское ядро, в качестве разделителя использовалось двоеточие, так что совет
          хотелось бы предостеречь от бездумного использования нативного File.separator
          скорее вреден чем полезен.
            0
            двоеточие — это вообще ересь — оно совершенно ни к чему.
            Бекслеш хотя бы на слеш похож по смыслу. А двоеточие откуда взялось?
              0
              Семантически двоеточие больше подходит чем слэш. Бэкслеш это совсем плохо.
            +10
            "/ — \ |" — это тот набор символов, который в DOS, да и вобще в консольном программировании использовался для отображения современного аналога часиков крутящихся ;)
              +2
              Автор, утверждение что операторы \/ и /\ были в ранних версиях C скорее всего ложное. И в википедии тоже :)
              Операторы && и || появились из операторов & и |, которые, в свою очередь, пришли из языка B
              (см. plan9.bell-labs.com/who/dmr/chist.html раздел Neonatal C)
                0
                Спасибо. Из текста убрал. Действительно, в вики никаких подтверждений этому факту нет, а нигде кроме как в той статье об этих операторах и языке С ни слова.
                0
                Автор, я все равно не понял. В MS-DOS ключи были отделен от пути пробелом. Какая нафиг разница, что в них уже есть слеш, если очень легко отделить путь от ключей?

                Честно я все равно не вижу логики. Ладно бы пробела не было, как в CP/M. Так МСДОС не поддерживал пробелы в именах AFAIK. То есть пробел однозначно отделял ключи от пути.

                Всё это объяснение выглядит натянуто.
                  0
                  Я не принимал участие в разработке MS-DOS, поэтому все что здесь написано в первой части — это результаты удовлетворения моего собственного любопытства. Так как моей квалификации явно недостаточно чтобы ответить на ваш вопрос, могу вам только предложить прочесть оригинальную статью «Why is the DOS path character „\“?». Ее написал Larry Osterman, который проработал в MS больше 25-ти лет, поэтому как минимум доля истинности в этой истории есть.
                  P.S.: Один из комментариев к оригинальному посту очень похож на ваш, но ответа на него никто не дал.
                  +1
                  Когда ещё был неопытным программером часто наступал на грабли, пропускав "\" в путях к файлу (писал «c:\newfile.txt» вместо «c:\\newfile.txt», язык C). Теперь в качестве разделителей всегда пишу с "/" вне зависимости от ОС — будь-то винда, будь-то линукс.
                    0
                    Да, слэши, экранирование и запуск кода на различных ОС — это о больном.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое