Если файл содержит обратную косую черту или символ новой строки, строка начинается с обратной косой черты, и каждый проблемный символ в имени файла экранируется обратной косой чертой, что делает вывод однозначным даже при наличии произвольных имен файлов.
( файл - это имя файла, а не его содержимое).
b2sum, sha1sumи различные инструменты SHA-2 ведут себя так же, как md5sum. sumи cksumнет; sumпредоставляется только для обратной совместимости (и его предки не производят цитируемый выход), и cksumэто определяется POSIX и не позволяет этого выхода.
Это поведение было введено в ноябре 2015 года и выпущено в версии 8.25 (январь 2016 года) со следующей NEWSзаписью:
md5sumтеперь обеспечивает единственную строку для каждого файла для статуса на стандартном выводе, используя '\' в начале строки и заменяя любые символы новой строки на '\ n'. Это также влияет sha1sum, sha224sum, sha256sum, sha384sumи sha512sum.
Обратная косая черта в начале строки служит в качестве флага: экранирование в именах файлов обрабатывается только в том случае, если строка начинается с обратной косой черты. (Unescaping не может быть поведением по умолчанию: он разрушит суммы, сгенерированные с более старыми версиями Coreutils, содержащими \\или \nсохраненными в именах файлов.)
Обидно, что-то совершенно не интуитивное, как это не описано на manстраницах. (И да, я знаю, что GNU хочет, чтобы все читали их чрезвычайно запутанные infoстраницы.)
roaima
3
@msouth обратная косая черта в начале строки служит флагом, указывающим, что обратная косая черта в имени файла является экранированием; в противном случае вы не знаете, обрабатывать ли и \nт.д. как литералы или экранированные символы.
Стивен Китт
3
@msouth, если оно в начале имени файла, у вас нет возможности узнать, флаг это или имя файла, начинающееся с обратной косой черты ...
Стивен Китт,
1
@ StefhenKitt Я не думаю, что ведущий \ здесь для устранения неоднозначности. Нет никакой двусмысленности, если выходные данные задокументированы как всегда экранирующие косые черты и переводы строки. Это так, что не нужно делать де-побег, если не нужно. Вы, конечно, можете спорить, стоит ли это того (лично я думаю, что это не так, но я не coreutilsпомогаю).
TypeIA
1
Фраза документации "каждый проблемный символ в имени файла экранирован с обратной косой чертой" неверна; замена новой строки на \nэто не то же самое, что экранирование новой строки с обратной косой чертой!
Руах
17
Ответ Стивена Китта охватывает вопрос « что?», И я постараюсь объяснить, почему это изменение было реализовано. Во-первых, кто-то заметил, что имя файла, содержащее перевод строки 1, может привести к неоднозначному выводу . Например, рассмотрим этот вывод:
d41d8cd98f00b204e9800998ecf8427e foo
25af89c92254a806b2e93fffd8ac1814 bar
Означает ли это, что было два файла fooи / barили только один файл с именем файла "foo\n25af89c92254a806b2e93fffd8ac1814 bar"? Конечно, эта последняя возможность крайне маловероятна, но она возможна. Чтобы устранить неоднозначность, разработчики решили экранировать символы новой строки с помощью обратной косой черты ( \). Выходной сигнал становится различимым. Однако тогда возникает еще одна двусмысленность:
764efa883dda1e11db47671c4a3bbd9e foo\nbar
Содержит ли имя этого файла символ новой строки или обратную косую черту с последующим n? Чтобы решить эту проблему, нам также необходимо избежать обратной косой черты, чтобы последний случай стал:
764efa883dda1e11db47671c4a3bbd9e foo\\nbar
Наконец, они решили добавить каждую выходную строку, содержащую такие экранированные символы, \\чтобы облегчить парсеру обнаружение выполнения экранирования. Предположительно это было сделано для того, чтобы парсеры могли обрабатывать выходные данные как из экранированных версий, так md5sumи из не экранированных версий (не-GNU). Этот флаг также означает, что «дорогостоящее» удаление не нужно делать, когда в этом нет необходимости. Вы можете увидеть пример этого анализа в действии md5sum.cсам по себе (строка 382 в связанной версии).
1 Под символом новой строки я подразумеваю символ, \nкоторый иногда также конкретно называют переводом строки или LF ; см md5sum.c.
Конечно, вменяемым поведением будет полный запрет каждого файла, содержащего перевод строки. Просто отказывайтесь их обрабатывать.
труба
1
@pipe это безумное поведение. POSIX допускает такие имена файлов, а утилиты, намеренно отказывающиеся работать с легитимными файлами, являются плохими и должны быть убиты огнем.
Руслан
2
@Ruslan Смысл в том, чтобы протестовать против POSIX за то, что он допускает такие антисоциальные имена. Разрешение таких символов, вероятно, вызвало большое количество проблем безопасности и раздувания кода только для обработки таких особых случаев.
труба
@pipe, в то время как LF в имени файла действительно антисоциальны, другие вещи, упомянутые в вашей ссылке, гораздо более спорны - например, пробелы, нелатинские буквы и т. д.
Руслан
Классический сверхинжиниринг от инженеров. Урок (еще раз): не позволяйте инженерам управлять требованиями. Они найдут самый непонятный и запутанный случай, превратят его в основной случай и запутают всех.
*sum
утилиты (того же семейства, чтоmd5sum
и e, g иsha1sum
т. Д.) В GNU coreutils делают то же самое.md5sum --version
cksum
нет; например% cksum test\\test 3915528286 4 test\test
cksum
это утилита POSIX и ее спецификация. не позволяет этого.Ответы:
Это задокументировано для Coreutils
md5sum
:( файл - это имя файла, а не его содержимое).
b2sum
,sha1sum
и различные инструменты SHA-2 ведут себя так же, какmd5sum
.sum
иcksum
нет;sum
предоставляется только для обратной совместимости (и его предки не производят цитируемый выход), иcksum
это определяется POSIX и не позволяет этого выхода.Это поведение было введено в ноябре 2015 года и выпущено в версии 8.25 (январь 2016 года) со следующей
NEWS
записью:Обратная косая черта в начале строки служит в качестве флага: экранирование в именах файлов обрабатывается только в том случае, если строка начинается с обратной косой черты. (Unescaping не может быть поведением по умолчанию: он разрушит суммы, сгенерированные с более старыми версиями Coreutils, содержащими
\\
или\n
сохраненными в именах файлов.)источник
man
страницах. (И да, я знаю, что GNU хочет, чтобы все читали их чрезвычайно запутанныеinfo
страницы.)\n
т.д. как литералы или экранированные символы.coreutils
помогаю).\n
это не то же самое, что экранирование новой строки с обратной косой чертой!Ответ Стивена Китта охватывает вопрос « что?», И я постараюсь объяснить, почему это изменение было реализовано. Во-первых, кто-то заметил, что имя файла, содержащее перевод строки 1, может привести к неоднозначному выводу . Например, рассмотрим этот вывод:
Означает ли это, что было два файла
foo
и /bar
или только один файл с именем файла"foo\n25af89c92254a806b2e93fffd8ac1814 bar"
? Конечно, эта последняя возможность крайне маловероятна, но она возможна. Чтобы устранить неоднозначность, разработчики решили экранировать символы новой строки с помощью обратной косой черты (\
). Выходной сигнал становится различимым. Однако тогда возникает еще одна двусмысленность:Содержит ли имя этого файла символ новой строки или обратную косую черту с последующим
n
? Чтобы решить эту проблему, нам также необходимо избежать обратной косой черты, чтобы последний случай стал:Наконец, они решили добавить каждую выходную строку, содержащую такие экранированные символы,
\\
чтобы облегчить парсеру обнаружение выполнения экранирования. Предположительно это было сделано для того, чтобы парсеры могли обрабатывать выходные данные как из экранированных версий, такmd5sum
и из не экранированных версий (не-GNU). Этот флаг также означает, что «дорогостоящее» удаление не нужно делать, когда в этом нет необходимости. Вы можете увидеть пример этого анализа в действииmd5sum.c
сам по себе (строка 382 в связанной версии).1 Под символом новой строки я подразумеваю символ,
\n
который иногда также конкретно называют переводом строки или LF ; смmd5sum.c
.источник