Jeśli plik zawiera odwrotny ukośnik lub nową linię, wiersz rozpoczyna się odwrotnym ukośnikiem, a każdy problematyczny znak w nazwie pliku jest poprzedzany odwrotnym ukośnikiem, dzięki czemu dane wyjściowe są jednoznaczne, nawet w obecności dowolnych nazw plików.
( plik to nazwa pliku, a nie jego zawartość).
b2sum, sha1suma różne narzędzia SHA-2 zachowują się w taki sam sposób jak md5sum. sumi cksumnie; sumjest zapewniony tylko dla kompatybilności wstecznej (a jego przodkowie nie wytwarzają danych wyjściowych cytowanych) i cksumjest określony przez POSIX i nie pozwala na ten typ danych wyjściowych.
md5sumteraz zapewnia jeden wiersz dla pliku dla statusu na standardowym wyjściu, używając „\” na początku wiersza i zastępując wszelkie nowe wiersze „\ n”. To także wpływa na sha1sum, sha224sum, sha256sum, sha384sumi sha512sum.
Odwrotny ukośnik na początku linii służy jako flaga: znaki ucieczki w nazwach plików są przetwarzane tylko wtedy, gdy linia zaczyna się od odwrotnego ukośnika. (Unescaping nie może być zachowaniem domyślnym: spowodowałoby to uszkodzenie sum wygenerowanych przez starsze wersje Coreutils zawierające \\lub \nw przechowywanych nazwach plików).
Szkoda, że coś zupełnie nieintuicyjnego nie jest udokumentowane na manstronach. (I tak, wiem, że GNU chce, aby wszyscy infozamiast tego czytali bardzo skomplikowane strony).
roaima
3
@msouth odwrotny ukośnik na początku wiersza służy jako flaga wskazująca, że odwrotne ukośniki w nazwie pliku są znakami ucieczki; w przeciwnym razie nie wiedziałbyś, czy przetworzyć \nitp. jako literały czy ucieczki.
Stephen Kitt
3
@msouth, jeśli jest na początku nazwy pliku, nie masz możliwości dowiedzieć się, czy jest to flaga, czy nazwa pliku naprawdę zaczyna się od odwrotnego ukośnika ...
Stephen Kitt
1
@StephenKitt Nie wydaje mi się, żeby wiodący \ był w stanie ujednoznacznić. Nie ma dwuznaczności, jeśli wynik jest udokumentowany jako zawsze unikający ukośników odwrotnych i znaków nowej linii. Ma to na celu zapobieganie ucieczce, jeśli nie jest konieczne. Możesz oczywiście zastanowić się, czy to jest tego warte (osobiście uważam, że nie jest, ale nie jestem coreutilsuczestnikiem).
TypeIA
1
Wyrażenie dokumentacji „każdy problematyczny znak w nazwie pliku jest poprzedzany ukośnikiem odwrotnym” jest niepoprawny; zastąpienie nowego wiersza znakiem \nnie jest tym samym, co ucieczka nowego wiersza odwrotnym ukośnikiem!
ruakh
17
Odpowiedź Stephena Kitta obejmuje to, co postaram się wyjaśnić, dlaczego wprowadzono tę zmianę. Po pierwsze, ktoś zauważył, że nazwa pliku zawierająca nowy wiersz 1 może powodować niejednoznaczne wyniki . Rozważmy na przykład:
d41d8cd98f00b204e9800998ecf8427e foo
25af89c92254a806b2e93fffd8ac1814 bar
Czy to oznacza, że były dwa pliki fooi barczy tylko jeden plik, którego nazwa pliku to "foo\n25af89c92254a806b2e93fffd8ac1814 bar"? To prawda, że ta ostatnia możliwość jest wysoce nieprawdopodobna, ale jest możliwa. Aby rozwiązać niejednoznaczność, programiści postanowili uciec od nowego wiersza za pomocą odwrotnego ukośnika ( \). Dane wyjściowe stają się następnie rozróżnialne. Istnieje jednak dalsza dwuznaczność:
764efa883dda1e11db47671c4a3bbd9e foo\nbar
Czy nazwa tego pliku zawiera znak nowej linii, czy odwrotny ukośnik, a po nim znak n? Aby rozwiązać ten problem, musimy również uciec z ukośników odwrotnych, aby ten drugi przypadek stał się:
764efa883dda1e11db47671c4a3bbd9e foo\\nbar
Na koniec postanowili wstawić do każdego wiersza wyjściowego, który zawiera takie znaki ucieczki, \\aby ułatwić analizatorowi parserowi wykrycie, czy zostało to wykonane. Prawdopodobnie zostało to zrobione, aby umożliwić parserom obsługę danych wyjściowych zarówno z wersji uciekających, jak i z wersji md5sumnie-uciekających (innych niż GNU). Flaga oznacza również, że „kosztownego” ucieczki nie trzeba wykonywać, gdy nie jest to konieczne. Możesz zobaczyć przykład tego parsowania w akcji md5sum.csam w sobie (wiersz 382 w wersji połączonej).
1 Dzięki nowej linii mam na myśli postać \n, która jest czasami również specjalnie określany jako wysuw wiersza lub LF ; zob md5sum.c.
Oczywiście rozsądnym zachowaniem byłoby całkowite zablokowanie każdego pliku zawierającego nowy wiersz. Po prostu odmów ich przetwarzania.
rura
1
@pipe to szalone zachowanie. POSIX zezwala na takie nazwy plików, a narzędzia celowo odmawiające pracy z prawidłowymi plikami są złe i muszą zostać zabite ogniem.
Ruslan
2
@Ruslan Chodzi o to, aby zaprotestować przeciwko POSIX za dopuszczenie takich aspołecznych nazwisk. Zezwolenie na takie znaki prawdopodobnie spowodowało wiele problemów związanych z bezpieczeństwem i rozdęcie kodu tylko w celu obsługi takich specjalnych przypadków.
rura
@pipe, podczas gdy LF w nazwie pliku jest rzeczywiście antyspołeczny, inne rzeczy wymienione w twoim linku są o wiele bardziej dyskusyjne - jak spacje, litery niełacińskie itp.
Ruslan
Klasyczna nadprodukcja przez inżynierów. Lekcja (jeszcze raz): nie pozwól inżynierom spełniać wymagań. Znajdą najbardziej niejasną i skomplikowaną sprawę i podniosą ją do sprawy dominującej i wprowadzą wszystkich w błąd.
*sum
narzędzia (z tej samej rodziny comd5sum
, e, gsha1sum
itp.) W jądrach GNU robią to samo.md5sum --version
cksum
nie; np.% cksum test\\test 3915528286 4 test\test
cksum
jest narzędziem POSIX i jego specyfikacją. nie pozwala na to.Odpowiedzi:
Jest to udokumentowane dla Coreutils
md5sum
:( plik to nazwa pliku, a nie jego zawartość).
b2sum
,sha1sum
a różne narzędzia SHA-2 zachowują się w taki sam sposób jakmd5sum
.sum
icksum
nie;sum
jest zapewniony tylko dla kompatybilności wstecznej (a jego przodkowie nie wytwarzają danych wyjściowych cytowanych) icksum
jest określony przez POSIX i nie pozwala na ten typ danych wyjściowych.To zachowanie zostało wprowadzone w listopadzie 2015 r. I wydane w wersji 8.25 (styczeń 2016 r.), Z następującym
NEWS
wpisem:Odwrotny ukośnik na początku linii służy jako flaga: znaki ucieczki w nazwach plików są przetwarzane tylko wtedy, gdy linia zaczyna się od odwrotnego ukośnika. (Unescaping nie może być zachowaniem domyślnym: spowodowałoby to uszkodzenie sum wygenerowanych przez starsze wersje Coreutils zawierające
\\
lub\n
w przechowywanych nazwach plików).źródło
man
stronach. (I tak, wiem, że GNU chce, aby wszyscyinfo
zamiast tego czytali bardzo skomplikowane strony).\n
itp. jako literały czy ucieczki.coreutils
uczestnikiem).\n
nie jest tym samym, co ucieczka nowego wiersza odwrotnym ukośnikiem!Odpowiedź Stephena Kitta obejmuje to, co postaram się wyjaśnić, dlaczego wprowadzono tę zmianę. Po pierwsze, ktoś zauważył, że nazwa pliku zawierająca nowy wiersz 1 może powodować niejednoznaczne wyniki . Rozważmy na przykład:
Czy to oznacza, że były dwa pliki
foo
ibar
czy tylko jeden plik, którego nazwa pliku to"foo\n25af89c92254a806b2e93fffd8ac1814 bar"
? To prawda, że ta ostatnia możliwość jest wysoce nieprawdopodobna, ale jest możliwa. Aby rozwiązać niejednoznaczność, programiści postanowili uciec od nowego wiersza za pomocą odwrotnego ukośnika (\
). Dane wyjściowe stają się następnie rozróżnialne. Istnieje jednak dalsza dwuznaczność:Czy nazwa tego pliku zawiera znak nowej linii, czy odwrotny ukośnik, a po nim znak
n
? Aby rozwiązać ten problem, musimy również uciec z ukośników odwrotnych, aby ten drugi przypadek stał się:Na koniec postanowili wstawić do każdego wiersza wyjściowego, który zawiera takie znaki ucieczki,
\\
aby ułatwić analizatorowi parserowi wykrycie, czy zostało to wykonane. Prawdopodobnie zostało to zrobione, aby umożliwić parserom obsługę danych wyjściowych zarówno z wersji uciekających, jak i z wersjimd5sum
nie-uciekających (innych niż GNU). Flaga oznacza również, że „kosztownego” ucieczki nie trzeba wykonywać, gdy nie jest to konieczne. Możesz zobaczyć przykład tego parsowania w akcjimd5sum.c
sam w sobie (wiersz 382 w wersji połączonej).1 Dzięki nowej linii mam na myśli postać
\n
, która jest czasami również specjalnie określany jako wysuw wiersza lub LF ; zobmd5sum.c
.źródło