Pertanyaan saya adalah mengapa harus menggunakan -r
flag (rekursif) ketika membuat salinan direktori? Yaitu, mengapa melakukan ini:
$ cp -r dir1 copyDir1
Kapan saya tidak ingin perilaku ini saat menyalin direktori?
Bukan salinan rekursif direktori yang benar-benar perilaku "default"; perilaku yang kita inginkan hampir setiap saat?
Rasanya seperti ini adalah bendera yang berlebihan.
rm
Jawaban:
Cara kerja filesystem, direktori sebenarnya bukan folder yang berisi file tetapi direktori adalah file yang berisi inode pointer ke file “child” yang terhubung dengannya. Artinya, dari perspektif sistem file, file adalah file, tetapi direktori hanyalah file yang berisi daftar file yang terhubung.
Jadi dari perspektif baris perintah, lakukan ini:
Pada dasarnya berarti menyalin nama file,
dir1
ke file baru bernamacopyDir1
. Dan sejauh menyangkut sistem file,dir1
tetap saja file; sebenarnya itu adalah "direktori" hanya akan terlihat ketika filesystem benar-benar memeriksadir1
untuk melihat apa tumpukan bit sebenarnya.The
-r
flag mengatakan sistem file untuk gulungan rekursif bawah file / pohon direktori dan menyalin setiap & semua isi yang mungkin menjadi “anak” dari file tersebut ke tempat baru.Sekarang mengapa itu mungkin tampak berlebihan atau berlebihan, ini benar-benar datang ke metode historis berurusan dengan sistem file. Serta menciptakan sistem yang aman dari semua jenis kesalahan terkait pengguna; disengaja serta disengaja.
Artinya, katakanlah Anda memiliki
~/bin
file di direktori home yang ingin Anda salin tetapi tidak sengaja meninggalkan~
— karena Anda adalah manusia dan melakukan kesalahan — jadi/bin
seperti ini:Dengan "jaring pengaman"
/bin
sebagai direktori yang dipadukan dengan kebutuhan akan-r
flag, Anda akan terhindar dari menyalin secara tidak sengaja seluruh akar biner dari sistem yang Anda gunakan pada direktori home Anda. Jika jaring pengaman itu tidak ada, bencana kecil - atau mungkin besar - akan terjadi.Logikanya di sini adalah bahwa pada hari-hari pra-GUI (antarmuka pengguna grafis) konvensi logis / perilaku perlu diatur untuk menghindari pengguna membuat kecelakaan yang berpotensi membunuh sistem. Dan menggunakan
-r
bendera sekarang adalah salah satunya.Jika itu tampak berlebihan, maka tidak perlu melihat lebih jauh dari sistem GUI modern yang dapat ditempatkan di atas sistem file Linux. GUI mengatasi masalah pengguna dasar seperti ini dengan memungkinkan orang menyeret dan menjatuhkan file dan direktori dengan mudah.
Tetapi dalam kasus bidang antarmuka berbasis teks, banyak "pengalaman pengguna" dalam dunia itu pada dasarnya hanya benjolan jalan yang logis dan berbasis hueristik yang membantu menjaga pengguna agar tetap terkendali sehingga potensi bencana dapat dihindari.
Demikian pula ini sebabnya sistem file Linux / Unix tidak memiliki
777
izin dansudo
hak yang ditetapkan secara default dan bagaimana administrator sistem nyata meringis ketika pengguna menetapkan777
izin atau memberikansudo
hak kepada semua orang . Ini adalah hal-hal dasar yang dilakukan seseorang untuk memastikan sistem stabil dan "bukti pengguna" mungkin; siapa pun yang terburu-buru untuk memutus konvensi tersebut kemungkinan besar akan menyebabkan kerusakan pada sistem mereka tanpa menyadarinya.INFO TAMBAHAN: Jawaban lain di sini di situs Unix Stack Exchange memberikan penjelasan yang baik tentang mengapa salinan direktori yang tidak rekursif bermasalah; penekanan adalah milikku.
Jadi, jika sebuah direktori hanyalah sebuah file dengan item inode di dalamnya, membuat salinan langsung dari file itu hanya akan setara dengan cara kerja tautan keras. Yang tidak diinginkan siapa pun.
sumber
cp -r /bin
sebagaicp-r ~/bin
. Bendera itu sendiri tidak mencegah kesalahan atau membuat orang lebih baik dalam berhati-hati. Jika Anda ingin mencegah kesalahan, perintah cp dapat dengan mudah melihat node yang dimaksud dan memberikan prompt, sesuatu di sepanjang baris "Ini adalah direktori, apakah Anda ingin menyalin semua konten ke lokasi yang ditentukan (y / n)? " Itu akan menjadi jaring pengaman . Memerlukan -r untuk direktori menjaga kode tetap turun lebih dari apa pun.Sangat benar bahwa ini adalah perilaku yang kita inginkan hampir setiap saat. Namun, ini tidak berarti bahwa menyalin secara rekursif harus menjadi perilaku default.
Saya pikir alasannya
cp
bertindak karena memang berakar pada filosofi Unix . Unix menyukai program yang melakukan satu hal dan melakukannya dengan baik , serta program yang sederhana di antarmuka dan implementasi (kadang-kadang disebut lebih buruk lebih baik ).Bagian penting dari teka-teki di sini adalah menyadari bahwa
cp
tidak menyalin direktori -cp
menyalin file (dan hanya file). Jika Anda ingin menyalin direktori,cp
panggil dirinya sendiri secara rekursif , untuk menyalin file pada setiap direktori.Tentu saja, perbedaan antara "menyalin direktori" dan "menyalin file secara rekursif" sama sekali tidak ada, dari perspektif pengguna, tetapi memiliki antarmuka ini membantu implementasinya tetap sederhana .
Jika Anda berhasil
cp
menyalin direktori, Anda akan segera tergoda untuk menambahkan lebih banyak fitur yang hanya masuk akal untuk direktori - misalnya, Anda mungkin ingin hanya menyalin nama file yang diakhiri dengan.sh
. Tidak dapat dihindari, ini mengarah pada bloat dan fitur creep yang biasa kita gunakan dalam sistem operasi lain - membuat perangkat lunak lambat, rumit dan rawan kesalahan.Keuntungan lain adalah memiliki
-r
juga membantu pengguna memahami apa yang sebenarnya terjadi di bawah antarmuka. Efek samping yang bagus dari ini adalah bahwa mempelajari konsep operasi rekursif akan membantu Anda ketika Anda belajar tentang alat lain yang mendukungnya (sepertigrep
, misalnya)Beberapa orang pasti akan memberi tahu Anda bahwa mengekspos detail implementasi kepada pengguna itu buruk , dan memiliki lebih banyak fitur bagus . Maksud saya di sini hanyalah menjelaskan alasan perilaku ini, jadi saya tidak akan mencoba berdebat dengan cara apa pun.
sumber
Interaksi dengan direktori memastikan Anda tahu Anda berinteraksi dengan direktori dan BUKAN hanya satu file.
Misalnya:
Jadi, jika Anda ingin berhasil menyalin folder, karena itu menyiratkan folder dan objek yang terkait dengan referensi folder, Anda harus memperlakukannya seolah-olah itu kumpulan file:
sumber
Konsekuensi dari mengubah default adalah bahwa ribuan script shell akan rusak. Ini mengarah pada persyaratan POSIX dan SUS untuk perilaku default yang sudah dikenal luas.
Alasannya adalah perkembangan historis perintah cp, ln dan mv (semua biner yang sama pada kebanyakan sistem UNIX lama) di berbagai cabang UNIX. Ketika
-r
muncul (awalcp
tidak memiliki opsi untuk menyalin direktori; di sini adalah halaman manual cp awal tanpa-r
atau-R
), ada berbagai perbedaan dalam menangani file khusus, symlink dan dan keanehan lain dari sistem file.Dari Spesifikasi Basis Grup Terbuka, Edisi 7 :
Bahkan Anda masih akan melihat beberapa orang secara teratur menggunakan:
Karena mereka tidak percaya bahwa
cp -r
implementasi dengan apa yang mereka gunakan pada mesin sewenang-wenang; Atau karena mereka menginginkantar
perilakunya.sumber
Ini mungkin UI suboptimal hari ini, tapi itu keputusan yang diambil sekitar tahun 1970 selama desain UNIX ketika disk jauh lebih mahal. Jutaan skrip shell bergantung padanya untuk bekerja seperti itu, dan sudah terlambat untuk mengubahnya.
Lihat artikel ini untuk info desain aslinya.
sumber
Keuntungan yang jelas dari
-r
flag adalah bahwa Anda dapatcp * /target/dir
menyalin hanya semua file di direktori sumber ke direktori target, menghilangkan (meskipun dengan peringatan) semua direktori yang terkandung di dalamnya.cp -r * /target/dir
akan menyalin semuanya sebagai gantinya, termasuk subdirektori.sumber
Anda memerlukan flag ini hanya ketika itu
cp
adalah perintah untuk menyalin file dan direktori dan bukan hanya direktori.Jika ada perintah khusus untuk salinan direktori, perilaku "default" pasti akan menjadi salinan rekursif.
sumber
mkdir
?Seperti yang disebutkan orang lain, direktori pada dasarnya hanyalah tipe file lain (berbeda dengan file biasa), yang biasanya "berisi" (menunjuk ke) file-file lain. Ini bisa berisi subdirektori, yang sama berlaku ...
Jadi jika Anda menyalin direktori (perspektif pengguna), Anda benar-benar menyalin banyak file (perspektif filesystem) (file biasa, file direktori, tautan simbolis, ...) dan untuk setiap file direktori, Anda mengulangi secara berulang bahwa proses. Karena menyalin direktori secara definisi merupakan proses rekursif, argumen cp disebut
--recursive
.Tentu saja sangat mudah untuk membuat pintasan perintah di lingkungan pengguna Anda (letakkan ini di file .profile / .bashrc Anda agar tersedia secara permanen):
Atau mungkin lebih baik:
Dengan begitu, Anda dapat menyalin direktori menggunakan
cpa dir1 copyDir1
dan itu tidak hanya akan mencetak apa yang sedang disalin tetapi juga menerapkan izin file.Dan karena seseorang menyebutkan bahwa cp secara teoritis dapat mendeteksi bahwa file sumber adalah direktori dan bertanya apakah itu harus menyalinnya secara rekursif, berikut saran singkatnya:
Ini hanya pembungkus cp murah. Itu selalu mempertahankan semua data meta (yaitu, menyalin waktu modifikasi file, benar menyalin symlinks dan sebagainya) dan jika Anda mencoba untuk menyalin direktori, ia bertanya apakah itu harus menyalinnya (secara rekursif).
sumber