Jika file berisi garis miring terbalik atau baris baru, baris dimulai dengan garis miring terbalik, dan setiap karakter yang bermasalah dalam nama file lolos dengan garis miring terbalik, membuat output tidak ambigu bahkan di hadapan nama file yang sewenang-wenang.
( file adalah nama file, bukan isi file).
b2sum,, sha1sumdan berbagai alat SHA-2 berperilaku dengan cara yang sama seperti md5sum. sumdan cksumjangan; sumhanya disediakan untuk mundur-kompatibilitas (dan nenek moyangnya tidak menghasilkan dikutip output), dan cksumini ditentukan oleh POSIX dan tidak memungkinkan jenis output.
md5sumsekarang memastikan satu baris per file untuk status pada output standar, dengan menggunakan '\' di awal baris, dan mengganti baris baru dengan '\ n'. Hal ini juga mempengaruhi sha1sum, sha224sum, sha256sum, sha384sumdan sha512sum.
Garis miring terbalik di awal baris berfungsi sebagai bendera: lolos dalam nama file hanya diproses jika garis dimulai dengan garis miring terbalik. (Penghapusan tidak bisa menjadi perilaku default: itu akan memecah jumlah yang dihasilkan dengan versi lama dari Coreutils yang mengandung \\atau \ndalam nama file yang disimpan.)
Sayang sekali sesuatu yang benar-benar tidak intuitif seperti ini tidak didokumentasikan di manhalaman. (Dan ya, saya sadar GNU ingin semua orang membaca infohalaman mereka yang sangat berbelit-belit .)
roaima
3
@ Mulut backslash di awal baris berfungsi sebagai bendera yang menunjukkan bahwa backslash dalam nama file adalah lolos; jika tidak, Anda tidak akan tahu apakah akan memproses \ndll sebagai literal atau lolos.
Stephen Kitt
3
@msouth jika itu di awal nama file, Anda tidak punya cara untuk mengetahui apakah itu bendera, atau nama file yang benar-benar dimulai dengan garis miring terbalik ...
Stephen Kitt
1
@StephenKitt Saya tidak berpikir terkemuka \ ada untuk disambiguasi. Tidak ada ambiguitas jika output didokumentasikan sebagai selalu lolos dari garis miring terbalik dan baris baru. Itu ada di sana sehingga pelarian tidak harus dilakukan jika tidak perlu. Anda tentu saja dapat memperdebatkan apakah ini layak (secara pribadi saya pikir itu tidak tetapi saya bukan coreutilskontributor)
TypeIA
1
Frasa dokumentasi "setiap karakter bermasalah dalam nama file lolos dengan backslash" salah; mengganti baris baru dengan \ntidak sama dengan melarikan diri baris baru dengan garis miring terbalik!
ruakh
17
Jawaban Stephen Kitt mencakup apa dan saya akan mencoba membahas mengapa perubahan ini diterapkan. Pertama, seseorang mengamati bahwa nama file yang mengandung baris baru 1 dapat menghasilkan output yang ambigu . Sebagai contoh, pertimbangkan output ini:
d41d8cd98f00b204e9800998ecf8427e foo
25af89c92254a806b2e93fffd8ac1814 bar
Apakah ini berarti ada dua file foodan bar, atau hanya satu file yang memiliki nama file "foo\n25af89c92254a806b2e93fffd8ac1814 bar"? Memang, kemungkinan yang terakhir ini sangat tidak mungkin, tetapi itu mungkin. Untuk mengatasi ambiguitas, pengembang memilih untuk keluar dari baris baru dengan backslash ( \). Output kemudian menjadi dapat dibedakan. Namun, kemudian ada ambiguitas lebih lanjut:
764efa883dda1e11db47671c4a3bbd9e foo\nbar
Apakah nama file ini mengandung baris baru, atau garis miring terbalik diikuti oleh n? Untuk mengatasi ini, kita juga harus melarikan diri dari garis miring terbalik, sehingga kasus terakhir menjadi:
764efa883dda1e11db47671c4a3bbd9e foo\\nbar
Akhirnya, mereka memilih untuk mendahului setiap jalur keluaran yang berisi pelarian seperti itu dengan a \\untuk memudahkan pengurai mendeteksi apakah pelolosan telah dilakukan. Agaknya hal ini dilakukan untuk memungkinkan parser menangani keluaran baik dari versi yang lolos md5sumdan dari versi yang tidak lolos (non-GNU). Bendera juga berarti bahwa "mahal" un-melarikan diri tidak perlu dilakukan ketika tidak perlu. Anda dapat melihat contoh tindakan parsing ini md5sum.csendiri (baris 382 dalam versi tertaut).
1 Dengan baris baru yang saya maksud adalah karakter \nyang kadang-kadang juga secara khusus disebut sebagai linefeed atau LF ; lihat md5sum.c.
Tentu saja perilaku waras adalah untuk sepenuhnya melarang setiap file yang berisi baris baru. Tolak saja untuk memprosesnya.
pipa
1
@pipe itu perilaku gila . POSIX memang mengizinkan nama file seperti itu, dan utilitas yang sengaja menolak untuk bekerja dengan file yang sah adalah buruk dan harus dibunuh dengan api.
Ruslan
2
@Ruslan Intinya adalah untuk memprotes POSIX karena mengizinkan nama antisosial tersebut . Membiarkan karakter seperti itu kemungkinan telah menyebabkan sejumlah besar masalah keamanan dan kode menggembung hanya untuk menangani kasus khusus tersebut.
pipa
@pipe sementara LF dalam nama file memang antisosial, hal-hal lain yang disebutkan dalam tautan Anda jauh lebih bisa diperdebatkan - seperti spasi, huruf non-latin dll.
Ruslan
Over-engineering klasik oleh para insinyur. Pelajaran (lagi-lagi): jangan izinkan insinyur mengarahkan persyaratan. Mereka akan menemukan kasus yang paling tidak jelas dan berbelit-belit dan mengangkatnya ke kasus yang mendominasi dan membingungkan semua orang.
*sum
utilitas lain (dari keluarga yang sama denganmd5sum
, e, g,sha1sum
dll.) Di GNU coreutils melakukan hal yang sama.md5sum --version
cksum
tidak; mis.% cksum test\\test 3915528286 4 test\test
cksum
utilitas POSIX dan spesifikasinya. tidak mengizinkannya.Jawaban:
Ini didokumentasikan , untuk Coreutils '
md5sum
:( file adalah nama file, bukan isi file).
b2sum
,,sha1sum
dan berbagai alat SHA-2 berperilaku dengan cara yang sama sepertimd5sum
.sum
dancksum
jangan;sum
hanya disediakan untuk mundur-kompatibilitas (dan nenek moyangnya tidak menghasilkan dikutip output), dancksum
ini ditentukan oleh POSIX dan tidak memungkinkan jenis output.Perilaku ini diperkenalkan pada November 2015 dan dirilis dalam versi 8.25 (Januari 2016), dengan
NEWS
entri berikut :Garis miring terbalik di awal baris berfungsi sebagai bendera: lolos dalam nama file hanya diproses jika garis dimulai dengan garis miring terbalik. (Penghapusan tidak bisa menjadi perilaku default: itu akan memecah jumlah yang dihasilkan dengan versi lama dari Coreutils yang mengandung
\\
atau\n
dalam nama file yang disimpan.)sumber
man
halaman. (Dan ya, saya sadar GNU ingin semua orang membacainfo
halaman mereka yang sangat berbelit-belit .)\n
dll sebagai literal atau lolos.coreutils
kontributor)\n
tidak sama dengan melarikan diri baris baru dengan garis miring terbalik!Jawaban Stephen Kitt mencakup apa dan saya akan mencoba membahas mengapa perubahan ini diterapkan. Pertama, seseorang mengamati bahwa nama file yang mengandung baris baru 1 dapat menghasilkan output yang ambigu . Sebagai contoh, pertimbangkan output ini:
Apakah ini berarti ada dua file
foo
danbar
, atau hanya satu file yang memiliki nama file"foo\n25af89c92254a806b2e93fffd8ac1814 bar"
? Memang, kemungkinan yang terakhir ini sangat tidak mungkin, tetapi itu mungkin. Untuk mengatasi ambiguitas, pengembang memilih untuk keluar dari baris baru dengan backslash (\
). Output kemudian menjadi dapat dibedakan. Namun, kemudian ada ambiguitas lebih lanjut:Apakah nama file ini mengandung baris baru, atau garis miring terbalik diikuti oleh
n
? Untuk mengatasi ini, kita juga harus melarikan diri dari garis miring terbalik, sehingga kasus terakhir menjadi:Akhirnya, mereka memilih untuk mendahului setiap jalur keluaran yang berisi pelarian seperti itu dengan a
\\
untuk memudahkan pengurai mendeteksi apakah pelolosan telah dilakukan. Agaknya hal ini dilakukan untuk memungkinkan parser menangani keluaran baik dari versi yang lolosmd5sum
dan dari versi yang tidak lolos (non-GNU). Bendera juga berarti bahwa "mahal" un-melarikan diri tidak perlu dilakukan ketika tidak perlu. Anda dapat melihat contoh tindakan parsing inimd5sum.c
sendiri (baris 382 dalam versi tertaut).1 Dengan baris baru yang saya maksud adalah karakter
\n
yang kadang-kadang juga secara khusus disebut sebagai linefeed atau LF ; lihatmd5sum.c
.sumber