Проблема в том, что в именах файлов в UNIX-подобных ОС (в Linux в том числе) запрещены лишь два символа: '
\0' (он же нулевой символ) и /, а все остальное разрешено. В имени файла может быть даже перевод строки!И эта особенность мешает правильно отображать имена (мало кто, думаю, умеет правильно показывать многострочные имена файлов). К тому же, становится невозможно парсить вывод утилит вроде
ls или find надежным образом. Действительно, ls обычно разделяет файлы переводом строки, а что если в самом имени файла встретится перевод строки? Правда, у find есть флаг -print0, который разделяет имена файлов нулевыми символами, но данные в таком формате надо как-то предобрабатывать, чтобы скормить в пайп другой программе.Еще происходят веселые вещи, если в имени файла есть специальные символы. Например:
$ touch $'\033[31;1mredfile\033[0m.txt'
$ ls
''$'\033''[31;1mredfile'$'\033''[0m.txt'
$ find .
.
./?[31;1mredfile?[0m.txt
$ echo *
redfile.txt
(после выполнения последней команды redfile будет выделен красным цветом)Здесь видно, что GNU'шные
find и ls заменяют спецсимволы на ?, поэтому вы никак не узнаете истинное имя файла, если будете парсить вывод этих утилит. Это поведение еще не портируемо; например, find из busybox выдаст$ busybox find .(и
.
./a
b.txt
./redfile.txt
redfile снова будет красным)А еще имя файла — произвольная последовательность байт, а в какой кодировке ее интерпретировать — остается на усмотрение пользовательских программ. Обычно в GNU/Linux все имена файлов записаны в UTF-8, но если криво установить локаль, то все имена на русском рискуют превратиться в тыкву.
На месте авторов UNIX я бы, наверное, запретил все символы с кодом меньше 32 в именах файлов. Еще я бы запрещал называть файлы невалидным UTF-8, но появление Юникода, увы, авторы оригинального UNIX предугадать не смогли бы. А добавить такой запрет позже сложно, потому что надо тянуть обратную совместимость.