Situasi:
$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat ‘foo/*’: No such file or directory)
Saya memiliki direktori yang penuh dengan folder dan file tersembunyi. Apa yang terjadi dan apa solusinya?
dotglob
diterjemahkanglobdots
oleh zsh yang merupakan nama opsi yang tidak valid untuk bash .Jawaban:
Penafian: Jawaban ini berkaitan dengan Bash secara khusus tetapi sebagian besar berlaku untuk pertanyaan mengenai pola glob!
Karakter bintang (
*
) adalah wildcard. Ada serangkaian karakter tertentu yang akan menggantikannya dan karakter pertama menjadi titik (.
) bukan salah satunya. Ini adalah kasus khusus hanya karena cara kerja sistem file Unix, file yang dimulai dengan titik dianggap "tersembunyi". Itu berarti bahwa alat-alat seperticp
,ls
, dll tidak akan "melihat" mereka kecuali secara eksplisit diperintahkan untuk melakukannya.Contohnya
Pertama mari kita buat beberapa data sampel.
Jadi sekarang kita memiliki yang berikut:
Sekarang mari kita mainkan beberapa game. Anda dapat menggunakan perintah
echo
untuk mencantumkan apa wildcard tertentu (*
) akan untuk perintah yang diberikan seperti:Mengubah perilaku?
Anda dapat menggunakan perintah
shopt -s dotglob
untuk mengubah perilaku*
sehingga selain file sepertiregfile1
itu juga akan cocok.dotfile1
.kutipan dari
bash
halaman manualContoh:
Anda dapat mengembalikan perilaku ini dengan perintah ini:
Situasi Anda?
Untuk Anda, Anda memberi tahu
cp
bahwa Anda ingin menyalin semua file yang sesuai dengan pola*
, dan tidak ada file.Atau Anda dapat melakukan ini jika Anda ingin semua yang ada di
foo
folder:Atau Anda bisa eksplisit:
Bentuk yang lebih ringkas menggunakan ekspansi brace di
bash
:Kapan saja Anda dapat menggunakan
echo
trik untuk melihat apa pola file yang Anda usulkan (itulah istilah mewah untuk bagian bintang itu).Kebetulan jika Anda akan menyalin direktori file + direktori lain, Anda biasanya ingin melakukan ini secara rekursif, itulah
-R
peralihan kecp
:sumber
shopt -s dotglob
,echo *
kemudian memberikan:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
biasanya tidak akan berfungsi karenacp
akan menolak untuk menyalinfoo
sendiri, mungkin maksud Andacp -R foo/. .
. (perhatikan itucp -R
yang standar).zsh
tidak termasuk.
dan..
dalam perluasan.*
. Dalamzsh
, jika suatu pola tidak cocok, perintah dibatalkan (cukup masuk akal lagi), sehingga dalam kasus umum,cp foo/{,.}* .
akan gagal jika tidak ada file yang tersembunyi atau tidak ada yang tersembunyi.shopt
tidak ada.Dengan
zsh
, cara tipikal adalah menggunakanD
kualifikasi glob (untuk memasukkan [D] file):Perhatikan bahwa dengan atau tanpa
D
, gumpalan zsh tidak pernah termasuk.
atau..
(seperti yang Anda harapkan).sumber
Shell memperlakukan file-file itu sebagai tersembunyi ketika ia menyelesaikan
*
karakter, jadicp
tidak menerima nama file ini sebagai argumen.Anda dapat menyalinnya dengan menentukan secara eksplisit
cp foo/.* .
sumber
Jika yang ingin Anda lakukan adalah menyalin semua file & direktori dari satu tempat ke tempat lain, Anda dapat menggunakan
rsync
perintah standar . Dalam contoh yang Anda berikan di atas:akan secara rekursif menyalin semua konten
foo
, termasuk file tersembunyi dan direktori tersembunyi, ke direktori saat ini. Garis miring pada akhirfoo/
adalah penting untuk rsync; dengan itu hanya isifoo
yang disalin, tanpa itu rsync akan menyalinfoo
juga. Sebagai contoh:-Ada banyak opsi lain yang tersedia untuk rsync, termasuk menyalin antar mesin.
sumber
Zsh Stéphane Chazelas ini jawaban benar untuk ekspresi tunggal dengan segumpal di dalamnya. Namun, jika Anda ingin mengaturnya untuk semua ekspresi secara default, Anda dapat menggunakannya
Masukkan ke dalam Anda
~/.zshrc
untuk membuatnya permanen.sumber