Saya memahami gagasan tentang hardlink dengan sangat baik, dan telah membaca halaman manual untuk alat dasar seperti cp
--- dan bahkan spesifikasi POSIX terbaru --- beberapa kali. Namun saya masih terkejut melihat perilaku berikut:
$ echo john > john
$ cp -l john paul
$ echo george > george
Pada titik ini john
dan paul
akan memiliki inode (dan konten) yang sama, dan george
akan berbeda dalam kedua hal. Sekarang kita lakukan:
$ cp george paul
Pada titik ini saya berharap george
dan paul
memiliki nomor inode yang berbeda tetapi konten yang sama --- harapan ini terpenuhi --- tetapi saya juga diharapkan paul
sekarang memiliki nomor inode yang berbeda dari john
, dan untuk john
masih memiliki konten john
. Di sinilah saya terkejut. Ternyata menyalin file ke jalur tujuan paul
juga memiliki hasil menginstal file yang sama (inode yang sama) di semua jalur tujuan lain yang berbagi paul
inode. Saya berpikir untuk cp
membuat file baru dan memindahkannya ke tempat yang sebelumnya ditempati oleh file lama paul
. Sebaliknya apa yang tampaknya dilakukan adalah membuka file yang ada paul
, memotongnya, dan menulisgeorge
Konten ke dalam file yang ada. Karenanya setiap file "lain" dengan inode yang sama mendapatkan konten "mereka" yang diperbarui secara bersamaan.
Oke, ini adalah perilaku sistematis dan sekarang setelah saya tahu untuk mengharapkannya, saya bisa mencari cara untuk mengatasinya, atau mengambil keuntungan darinya, jika perlu. Apa yang membingungkan saya di mana saya seharusnya melihat perilaku ini didokumentasikan? Saya akan terkejut jika itu tidak didokumentasikan di suatu tempat di dokumen yang sudah saya lihat. Tetapi ternyata saya melewatkannya, dan sekarang tidak dapat menemukan sumber yang membahas perilaku ini.
cp
dokumen yang menimpa file tujuan jika file tujuan sudah ada. Anda benar bahwa itu tidak menentukan secara rinci apa arti "menimpa", tetapi jelas mengatakan "menimpa", bukan "mengganti". Jika Anda ingin menjadi orang yang bertele-tele, Anda dapat berargumen bahwa "menimpa" adalah apa yangcp
dilakukannya, dan perilaku yang Anda harapkan akan disebut "ganti".Juga perhatikan bahwa jika
cp
"mengganti" file tujuan yang sudah ada sebelumnya, yang mungkin dianggap mengejutkan atau salah, mungkin lebih dari sekadar "menimpa". Sebagai contoh:cp
pertama kali menghapus file lama dan kemudian membuat yang baru maka akan ada interval waktu di mana file tersebut akan tidak ada, yang akan mengejutkan.cp
pertama kali membuat file sementara dan kemudian memindahkannya di tempat maka mungkin harus mendokumentasikan ini, karena fakta bahwa file sementara seperti itu dengan nama-nama aneh kadang-kadang akan diperhatikan ... tetapi tidak.cp
tidak dapat membuat file baru di direktori yang sama dengan file lama karena izin maka ini akan sangat disayangkan (terutama jika sudah menghapus yang lama).cp
dan pengguna yang menjalankannyacp
tidakroot
maka tidak mungkin untuk mencocokkan pemilik & izin dari file baru dengan file yang baru.cp
tidak diketahui, maka ini akan hilang dalam salinan. Saat ini implementasicp
seharusnya dapat memahami hal-hal seperti atribut yang diperluas, tetapi tidak selalu demikian. Dan ada hal-hal lain, seperti garpu sumber daya MacOS, atau, untuk sistem file jarak jauh, pada dasarnya apa saja.Jadi kesimpulannya: sekarang Anda tahu apa yang
cp
sebenarnya. Anda tidak akan terkejut dengan itu lagi! Jujur, saya pikir hal yang sama mungkin terjadi pada saya juga, bertahun-tahun yang lalu.sumber
man
halaman untukcp
pada BSD (setidaknya, OSX) dan versi Gnucp
tidak begitu eksplisit tentang "menimpa". Kata itu hanya digunakan di komentar pada opsi-i
dan-n
. Halaman manual Gnu terutama tidak informatif, mulaiCopy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
halaman manual BSD / Mac setidaknya mengatakanIn the first synopsis form, the cp utility copies the contents of the source_file to the target_file.
‘cp’ copies files (or, optionally, directories). The copy is completely independent of the original.
Saya melihat bahwa standar POSIX 2013 tidak menentukan perilaku yang diamati . Ia mengatakan:
sumber
cp
akan memberikan hasil yang serupamv
, dan memutuskan tautan apa pun yang menjadi bagian darinya. Tapi sekarang saya berpikir tentang hal itu, itu berarti harus secara khususunlink(2)
target (cp -f
), atau membuat sementara yang berbeda bernama dan kemudianrename(2)
. Implementasi yang mudah adalah dengan hanya membuka file untuk ditimpa, yang merupakan persyaratan POSIX. Ini setara dengancat src > dest
Jika Anda dapat mengatakan, "menyalin file ke jalur tujuan
paul
juga menyalin file yang sama (inode yang sama) ke semua jalur tujuan lain yang berbagipaul
inode.", Saya minta maaf untuk mengatakan bahwa Anda tidak memahami gagasan tentang tautan keras dengan sangat baik. Jika saya memberikan sebuah apel kepada Sir McCartney, saya telah memberikan sebuah apel kepada Paul, dan saya telah memberikan sebuah apel kepada mitra penulis lagu John Lennon. Tapi saya belum membagikan tiga apel; Saya telah memberikan sebuah apel kepada seseorang yang memiliki banyak nama / gelar / deskriptor.Demikian pula, ketika Anda menyalin
george
kepaul
, Anda tidak juga menyalin kejohn
. Sebaliknya, Anda menyalingeorge
data ke file yang inode-nya ditunjukkan olehpaul
entri direktori.Langkah demi langkah: Saat Anda melakukannya
Anda telah membuat file baru (dengan asumsi bahwa belum ada file bernama
john
di direktori itu). Atau, untuk berbicara lebih ketat, ini mengasumsikan bahwa belum ada entri direktori dengan namajohn
di direktori itu (karena, secara tegas, tidak ada file dalam direktori; hanya entri direktori, yang mengarah ke inode). Setelah kamu lakukanatau
Anda belum membuat file baru; sebaliknya, Anda telah memberi nama baru pada file Anda yang sudah ada. Anda sekarang memiliki file dengan dua nama:
john
danpaul
. Dan ketika Anda mengatakannyaAnda menimpa file itu . Fakta bahwa ia memiliki dua nama tidak relevan; itu bisa memiliki 42 nama, mungkin di tempat-tempat yang Anda bahkan tidak dapat mengakses, dan perintah ini tidak akan menyalin
george\n
data ke semua nama (jalur); itu hanya menyalin data ke satu file yang memiliki banyak nama.sumber
john
danpaul
mulai sebagai dua nama path untuk file yang sama. Tetapi itu adalah cara termudah yang bisa saya pikirkan untuk mengekspresikan diri. Saya tidak berpikir gagasan tentang hubungan yang sulit, dipahami dengan benar, menentukan salah satu dari dua perilaku untukcp
(tanpa-l
).