perbedaan isi folder copy antara /. dan / * di linux

8

untuk menyalin konten dari folder yang telah saya baca, penggunaannya adalah:

cp -rfva ../foldersource/. ./

tapi ini juga berhasil

cp -rfva ../foldersource/* ./

apakah ada perbedaan?

dengan contoh jika saya ingin menghapus konten dari folder dengan. :

rm -rf ../foldersource/.

saya mendapatkan kesalahan:

rm:  rejet delete folder '.' or '..':

tetapi dengan tanda bintang tidak apa-apa

rm -rf ../foldersource/*

jadi, asterisk adalah opsi yang lebih baik yang bekerja di mana saja?

stackdave
sumber

Jawaban:

10

Ada perbedaan mendasar antara kedua bentuk argumen ini. Dan ini penting untuk memahami apa yang terjadi.

Dengan ../foldersource/.argumen dilewatkan tidak berubah ke perintah, apakah itu cpatau rmatau sesuatu yang lain. Terserah perintah apakah trailing dot itu memiliki semantik khusus atau unik yang berbeda dari konvensi Unix standar dengan hanya menunjuk ke direktori tempat ia berada; keduanya rmdan cptampaknya memperlakukannya sebagai kasus khusus.

Dengan ../foldersource/*argumen pertama kali diperluas oleh shell sebelum perintah bahkan pernah dieksekusi dan melewati argumen apa pun. Jadi, rmtidak pernah melihat ../foldersource/*; ia melihat versi yang diperluas ../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1dan seterusnya. Ini penting karena sistem operasi membatasi berapa banyak argumen yang dapat diteruskan ke perintah, biasanya hanya beberapa ratus.

eestrada
sumber
4
It's up to the command whether that trailing dot makes any senseUm, titik selalu terhubung ke direktori yang berisi itu sendiri, jadi ../foldersource/.seharusnya tidak berbeda dengan menyatakan ./foldersource/dan sebenarnya itu hanya cara yang berlebihan untuk menyatakan hal yang sama. Tidak ada perintah yang mencoba "memahami" dot atau double dot, karena ini adalah standar pada sistem file Linux / Unix. rmcukup menolak menghapus direktori kerja saat ini seperti yang jimmijdinyatakan dalam jawaban mereka. Perhatikan juga bahwa Anda menggunakan ./semua contoh Anda saat OP ../ada di sana. Agak dari perbedaan (besar).
Sergiy Kolodyazhnyy
"cp -rfva ../foldersource/ ./" sama dengan "cp -rfva ../foldersource ./", saya ingin menyalin konten folderource, tetapi bukan folder root
stackdave
1
@Stackdave no, cp -rfva ../foldersource/. ./ TIDAK setara dengan cp -rfva ../foldersource ./ . Trailing /.signifikan
roaima
2
Walaupun apa yang dikatakan jawaban ini benar, namun ada perbedaan yang sangat penting seperti disebutkan dalam jawaban @ roaima: varian / * tidak (biasanya) menyalin file atau direktori yang diawali dengan.
Adam
@SergiyKolodyazhnyy Anda benar; yang .merupakan konvensi standar dalam Unix untuk menunjukkan saat ini secara langsung. Juga, terima kasih telah menunjukkan bahwa saya telah menggunakan ./contoh saya ketika saya seharusnya menggunakannya ../; Saya akan memperbaikinya. Anda salah tentang apakah perintah "masuk akal" dari trailing dot; seperti yang ditunjukkan OP (dan saya alami dengan cp) keduanya rmdan cpberperilaku berbeda ketika trailing .hadir. Saya seharusnya menulis sesuatu seperti "terserah perintah jika trailing dot memiliki semantik khusus atau unik". Saya akan mengubah jawaban saya untuk kejelasan.
eestrada
10

Ketika Anda menyalin menggunakan cp -a source/* target/Anda menyalin sebagian besar file dan direktori dari sourceke target. Khususnya, item yang dikecualikan mungkin akan menjadi file yang dimulai dengan titik ( .) di tingkat atas source.

Pertimbangkan file-file ini (atau direktori) di source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will not be copied

Ketika Anda menyalin menggunakan cp -a source/. target/Anda menyalin seluruh konten source, termasuk item yang dimulai dengan titik ( .) ketarget

Pertimbangkan file-file ini (atau direktori) di source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will be copied

Jika Anda menggunakan bash,, zshAnda dapat menggunakan dotglobopsi untuk mengubah arti *sehingga menyertakan file dan direktori yang dimulai dengan titik ( yashjuga memiliki dotglobopsi; namun, ia kemudian menyertakan .dan ..dalam ekspansi glob yang membatasi kegunaannya. Lihat juga FIGNORE='@(.|..)'dalam ksh93).

Menariknya, cp -a source/. target/dijamin tidak akan pernah membuat komponen target/source. (Di sisi lain, cp -a source target/akan melakukan salah satu dari dua hal tergantung pada apakah targetsudah ada atau tidak . Lihat Cara menyalin folder secara rekursif dengan cara idempoten menggunakan cp untuk detailnya.)


Ketika Anda menghapus menggunakan rm -rf source/*Anda menghapus file dan direktori di dalamnya sourceyang tidak dimulai dengan titik ( .). Tunduk pada dotglobpengaturan yang telah saya sebutkan. Itu tidak akan menghapus direktori sourceitu sendiri.

Ketika Anda mencoba menghapusnya, rm -rf source/.ia akan gagal - seperti yang sudah dijelaskan orang lain - karena POSIX melarang penghapusan lintasan yang komponen terakhirnya .atau ... Setara terdekat adalah rm -rf source, yang akan menghapus sourcedirektori dan semua kontennya terlepas dari apakah mereka memulai dengan titik ( .).

roaima
sumber
1
Lihat juga Apakah 'rm. *' Pernah menghapus direktori induk? tentang rm -rf .gagal .
Stéphane Chazelas
7

Anda tidak dapat melakukannya rm -rf ../foldersource/.karena rmtidak mengizinkan ini, seperti yang dinyatakan secara eksplisit dalam manual:

Upaya apa pun untuk menghapus file yang komponen nama file terakhirnya adalah '.' atau '..' ditolak tanpa diminta, seperti yang diamanatkan oleh POSIX.

dan dalam manual POSIX man 1p rmkita melihat:

Jika salah satu dari file dot atau dot-dot ditetapkan sebagai bagian nama dasar dari operan (yaitu, komponen pathname akhir) atau jika operan memutuskan ke direktori root, rm harus menulis pesan diagnostik ke kesalahan standar dan tidak melakukan apa pun. lebih banyak dengan operan tersebut.

jimmij
sumber