md5sum попередньо '\' до контрольної суми


22

Чому md5sum передує "\" перед контрольною сумою, коли знаходить контрольну суму файлу з іменем "\"?

$ md5sum /tmp/test\\test
\d41d8cd98f00b204e9800998ecf8427e  /tmp/test\\test

Те саме відмічено для кожної іншої утиліти.


Як тільки для довідки, інші *sumутиліти (того ж сімейства, як md5sum, e, g sha1sumтощо) в GNU coreutils роблять те саме.
Кусалаланда

Я не бачу такої поведінки, яка версія утиліти:md5sum --version
Kiwy

@Kusalananda Це може бути специфічна версія Coreutils; на CentOS 7 cksumнемає; наприклад% cksum test\\test 3915528286 4 test\test
Стівен Харріс

@StephenHarris Це, мабуть , тому cksum, що це утиліта POSIX та її специфікація. не дозволяє.
Kusalananda

Відповіді:


33

Це документально підтверджено для Coreutils md5sum:

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

( файл - це ім'я файлу, а не вміст файлу).

b2sum, sha1sumі різні інструменти SHA-2 поводяться так само, як і md5sum. sumі cksumні; sumнадається тільки для зворотної сумісності (і його предки не виробляють цитований вихід), і cksumце визначається POSIX і не дозволяє цього виходу.

Така поведінка була введена в листопаді 2015 року та опублікована у версії 8.25 (січень 2016 року) із наступним NEWSзаписом:

md5sumтепер забезпечує один рядок у файлі для статусу на стандартному виході, використовуючи "\" на початку рядка та замінюючи будь-які нові рядки на "\ n". Це також впливає sha1sum, sha224sum, sha256sum, sha384sumі sha512sum.

Нахил на початку рядка служить прапором: вхідні файли в імені файлів обробляються лише в тому випадку, якщо рядок починається з нахилу. (Невизначення масштабу не може бути поведінкою за замовчуванням: воно порушить суми, згенеровані за старими версіями Coreutils, що містять \\або \nзберігаються назви файлів.)


30
Соромно щось зовсім неінтуїтивне, як це не зафіксовано на manсторінках. (І так, я знаю, що GNU хоче, щоб усі читали infoзамість них досить
перекручені

3
@south штрих на початку рядка служить прапором, що вказує на те, що косої косий риски у назві файлу є втечею; інакше ви б не знали, обробляти \nтощо як буквальні чи втечі.
Стівен Кітт

3
@msouth, якщо він знаходиться на початку імені файлу, ви не можете дізнатися, чи це прапор, чи ім'я файлу, що справді починається зі зворотної косої риси ...
Stephen Kitt

1
@StephenKitt Я не думаю, що ведучі \ є для розбіжностей. Немає двозначності, якщо результат документально зафіксований як завжди протікає з косою рискою та новими рядками. Це там, щоб зняти втечу не потрібно робити, якщо не потрібно. Можна, звичайно, дискутувати, чи варто цього (особисто я думаю, що це не так, але я не є coreutilsучасником).
TypeIA

1
Фраза документації "кожен проблемний символ у назві файлу ухиляється із зворотною косою рисою" неправильна; заміна нового рядка на \nне є тим самим, як уникнення нового рядка з нахилом!
ruakh

17

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

d41d8cd98f00b204e9800998ecf8427e  foo
25af89c92254a806b2e93fffd8ac1814  bar

Чи означає це, що було два файли fooта barчи лише один файл, ім'я якого файлу "foo\n25af89c92254a806b2e93fffd8ac1814 bar"? Звичайно, ця остання можливість є малоймовірною, але вона можлива. Щоб вирішити двозначність, розробники вирішили вийти з нових рядків із зворотною косою рисою ( \). Потім результат стає помітним. Однак тоді є ще одна неоднозначність:

764efa883dda1e11db47671c4a3bbd9e  foo\nbar

Чи містить ім'я цього файлу з нового рядка або зворотної косої межі , за яким слід n? Щоб вирішити цю проблему, нам потрібно уникати зворотних нахилів, щоб останній випадок став:

764efa883dda1e11db47671c4a3bbd9e  foo\\nbar

Нарешті, вони вирішили доповнити кожен вихідний рядок, який містить такі вхідні знаки, з \\полегшенням для аналізатора виявити, чи було виконано проходження. Імовірно, це було зроблено для того, щоб дозволити парсерам обробляти висновки як з епізодуючих версій, так md5sumі з невідбійних версій (non-GNU). Прапор також означає, що "дорогого" відключення не потрібно робити, коли це не потрібно. Ви можете бачити приклад цього розбору в дії md5sum.cсам по собі (рядок 382 у пов'язаній версії).


1 Під новим рядком я маю на увазі персонажа, \nякий іноді також конкретно називають передавачем ліній або LF ; див md5sum.c.


1
Звичайно, розумною поведінкою було б повністю заборонити кожен файл, що містить новий рядок. Просто відмовтеся їх обробляти.
труба

1
@pipe це божевільна поведінка. POSIX дозволяє такі імена файлів, і утиліти навмисно відмовляються працювати з законними файлами - це погано і їх потрібно вбити вогнем.
Руслан

2
@Ruslan Справа в тому, щоб протестувати проти POSIX за дозвол таких асоціальних імен. Дозволення таких символів, ймовірно, спричинило велику кількість проблем із безпекою та роздуття коду саме для вирішення таких особливих випадків.
труба

@pipe, хоча LF у назві файлу справді антисоціальний, інші речі, згадані у вашому посиланні, є набагато дискусійнішими - як пробіли, не латинські літери тощо.
Руслан,

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