md5sum trả trước '\' cho tổng kiểm tra


22

Tại sao md5sum lại trả trước "\" trước tổng kiểm tra khi tìm tổng kiểm tra của tệp có "\" trong tên?

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

Điều tương tự được ghi nhận cho mọi tiện ích khác.


Chỉ để tham khảo, các *sumtiện ích khác (cùng họ md5sum, e, g, sha1sumv.v.) trong lõi GNU cũng làm như vậy.
Kusalananda

Tôi không thấy hành vi này, phiên bản của tiện ích là gì:md5sum --version
Kiwy

@Kusalananda Đây có thể là phiên bản coreutils cụ thể; trên CentOS 7 cksumkhông; ví dụ% cksum test\\test 3915528286 4 test\test
Stephen Harris

@StephenHarris Đó có lẽ là vì cksumtiện ích POSIX và thông số kỹ thuật của nó. không cho phép nó.
Kusalananda

Câu trả lời:


33

Đây là tài liệu , cho Coreutils ' md5sum:

Nếu tệp chứa dấu gạch chéo ngược hoặc dòng mới, dòng được bắt đầu bằng dấu gạch chéo ngược và mỗi ký tự có vấn đề trong tên tệp được thoát bằng dấu gạch chéo ngược, làm cho đầu ra không rõ ràng ngay cả khi có tên tệp tùy ý.

( tệp là tên tệp, không phải nội dung của tệp).

b2sum, sha1sumvà các công cụ SHA-2 khác nhau hoạt động theo cùng một cách như md5sum. sumcksumđừng; sumchỉ được cung cấp để tương thích ngược (và tổ tiên của nó không tạo ra đầu ra được trích dẫn) và cksumđược chỉ định bởi POSIX và không cho phép loại đầu ra này.

Hành vi này được giới thiệu vào tháng 11 năm 2015 và được phát hành trong phiên bản 8.25 (tháng 1 năm 2016), với NEWSmục sau :

md5sumhiện đảm bảo một dòng trên mỗi tệp cho trạng thái trên đầu ra tiêu chuẩn, bằng cách sử dụng '\' ở đầu dòng và thay thế bất kỳ dòng mới nào bằng '\ n'. Điều này cũng ảnh hưởng sha1sum, sha224sum, sha256sum, sha384sumsha512sum.

Dấu gạch chéo ngược ở đầu dòng đóng vai trò là cờ: thoát trong tên tệp chỉ được xử lý nếu dòng bắt đầu bằng dấu gạch chéo ngược. (Unescaping không thể là hành vi mặc định: nó sẽ phá vỡ các khoản tiền được tạo bằng các phiên bản Coreutils cũ hơn có chứa \\hoặc \ntrong tên tệp được lưu trữ.)


30
Mặc dù đó là một điều đáng xấu hổ hoàn toàn không trực quan như thế này không được ghi lại trong các mantrang. (Và vâng, tôi biết GNU muốn mọi người đọc các infotrang rất phức tạp của họ .)
roaima

3
@msouth dấu gạch chéo ngược ở đầu dòng đóng vai trò là cờ cho biết dấu gạch chéo ngược trong tên tệp là thoát; nếu không, bạn sẽ không biết nên xử lý \nvv như là nghĩa đen hoặc thoát.
Stephen Kitt

3
@msouth nếu bắt đầu tên tệp, bạn không có cách nào để biết đó là cờ hay tên tệp thực sự bắt đầu bằng dấu gạch chéo ngược ...
Stephen Kitt

1
@StephenKitt Tôi không nghĩ rằng hàng đầu \ là có sự định hướng. Không có sự mơ hồ nếu đầu ra được ghi lại là luôn thoát khỏi dấu gạch chéo ngược và dòng mới. Nó ở đó để việc thoát hiểm không cần phải được thực hiện nếu không cần thiết. Tất nhiên bạn có thể tranh luận liệu điều này có đáng không (cá nhân tôi nghĩ rằng nó không nhưng tôi không phải là người coreutilsđóng góp).
TypeIA

1
Cụm từ của tài liệu "mỗi ký tự có vấn đề trong tên tệp được thoát bằng dấu gạch chéo ngược" là sai; thay thế một dòng mới bằng \nkhông giống như thoát một dòng mới bằng dấu gạch chéo ngược!
ruakh

17

Câu trả lời của Stephen Kitt bao gồm những gì và tôi sẽ cố gắng giải thích tại sao thay đổi này được thực hiện. Đầu tiên, ai đó quan sát thấy rằng một tên tệp chứa dòng mới 1 có thể dẫn đến đầu ra mơ hồ . Ví dụ, hãy xem xét đầu ra này:

d41d8cd98f00b204e9800998ecf8427e  foo
25af89c92254a806b2e93fffd8ac1814  bar

Điều này có nghĩa là có hai tệp foobarchỉ một tệp có tên tệp là "foo\n25af89c92254a806b2e93fffd8ac1814 bar"? Cấp, khả năng sau này là rất khó xảy ra, nhưng nó có thể. Để giải quyết sự mơ hồ, các nhà phát triển đã chọn thoát dòng mới bằng dấu gạch chéo ngược ( \). Đầu ra sau đó trở nên phân biệt. Tuy nhiên, sau đó có một sự mơ hồ hơn nữa:

764efa883dda1e11db47671c4a3bbd9e  foo\nbar

Tên của tệp này có chứa một dòng mới hoặc dấu gạch chéo ngược theo sau nkhông? Để giải quyết vấn đề này, chúng ta cũng cần thoát dấu gạch chéo ngược để trường hợp sau trở thành:

764efa883dda1e11db47671c4a3bbd9e  foo\\nbar

Cuối cùng, họ đã chọn để trả trước mỗi dòng đầu ra có chứa các lối thoát như vậy \\để giúp trình phân tích cú pháp dễ dàng phát hiện xem việc thoát đã được thực hiện hay chưa. Có lẽ điều này đã được thực hiện để cho phép các trình phân tích cú pháp xử lý đầu ra cả từ các phiên bản thoát md5sumvà từ các phiên bản không thoát (không phải GNU). Cờ cũng có nghĩa là không thoát "tốn kém" không cần thiết phải thực hiện khi không cần thiết. Bản thân bạn có thể thấy một ví dụ về phân tích cú pháp này md5sum.c(dòng 382 trong phiên bản được liên kết).


1 Theo dòng mới, ý tôi là nhân vật \nđôi khi cũng được gọi cụ thể là linefeed hoặc LF ; thấy md5sum.c.


1
Tất nhiên hành vi lành mạnh sẽ là cấm hoàn toàn mọi tệp có chứa một dòng mới. Chỉ cần từ chối xử lý chúng.
đường ống

1
@pipe đó là hành vi điên rồ . POSIX không cho phép các tên tệp như vậy và các tiện ích cố tình từ chối làm việc với các tệp hợp pháp là xấu và phải bị giết bằng lửa.
Ruslan

2
@Ruslan Vấn đề là phản đối POSIX vì đã cho phép những tên chống đối xã hội như vậy . Việc cho phép các nhân vật như vậy có thể đã gây ra một số lượng lớn các vấn đề bảo mật và sự phình to mã chỉ để xử lý các trường hợp đặc biệt như vậy.
đường ống

@pipe khi LF trong một tên tập tin thực sự là chống đối xã hội, mọi thứ khác được đề cập trong liên kết của bạn được nhiều hơn nữa gây tranh cãi - như khoảng trắng, chữ phi Latin vv ..
Ruslan

Kỹ thuật quá cổ điển của các kỹ sư. Bài học (một lần nữa): không cho phép các kỹ sư lái xe yêu cầu. Họ sẽ tìm thấy trường hợp khó hiểu và phức tạp nhất và nâng nó lên trường hợp thống trị và làm mọi người bối rối.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.