Jadi perilaku unix berikut ini hanya merugikan saya:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Bagaimana ini masuk akal?
Jadi perilaku unix berikut ini hanya merugikan saya:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Bagaimana ini masuk akal?
Jawaban:
Baris perintah find dibuat dari berbagai jenis opsi, yang digabungkan untuk membentuk ekspresi.
The find
pilihan -delete
adalah tindakan.
Itu berarti dijalankan untuk setiap file yang cocok sejauh ini.
Sebagai opsi pertama setelah jalur, semua file dicocokkan ... oops!
Ini berbahaya - tetapi halaman manual setidaknya memiliki peringatan besar :
Dari man find
:
ACTIONS
-delete
Delete files; true if removal succeeded. If the removal failed, an
error message is issued. If -delete fails, find's exit status will
be nonzero (when it eventually exits). Use of -delete automatically
turns on the -depth option.
Warnings: Don't forget that the find command line is evaluated as an
expression, so putting -delete first will make find try to delete
everything below the starting points you specified. When testing a
find command line that you later intend to use with -delete, you
should explicitly specify -depth in order to avoid later surprises.
Because -delete implies -depth, you cannot usefully use -prune and
-delete together.
Dari lebih lanjut di man find
:
EXPRESSIONS
The expression is made up of options (which affect overall operation rather
than the processing of a specific file, and always return true), tests
(which return a true or false value), and actions (which have side effects
and return a true or false value), all separated by operators. -and is
assumed where the operator is omitted.
If the expression contains no actions other than -prune, -print is per‐
formed on all files for which the expression is true.
Saat mencoba apa yang find
akan dilakukan perintah:
Untuk melihat seperti apa perintahnya
find . -name '*ar' -delete
akan menghapus, pertama-tama Anda dapat mengganti tindakan -delete
dengan tindakan yang lebih tidak berbahaya - seperti -fls
atau -print
:
find . -name '*ar' -print
Ini akan mencetak file mana yang dipengaruhi oleh tindakan.
Dalam contoh ini, -cetak dapat ditinggalkan. Dalam hal ini, tidak ada tindakan sama sekali, jadi yang paling jelas ditambahkan secara implisit: -print
. (Lihat paragraf kedua bagian "EKSPRESI" yang dikutip di atas)
-delete
bendera :-) Tapi apakah ada alasan orang akan pernah lakukan find . -delete
bukan rm -rf .
? Atau apakah itu hanya terjadi dengan cara find
mem-parsing dan memproses argumennya?
warning: use -depth when testing stuff you later want to -delete
yang tidak Anda lakukan sebagai contoh praktis?
-n
opsi; Perintah pertama seharusnya tidak memiliki penggunaan praktis sama sekali, tentu saja; Saya akan mengubahnya.
Dalam find
urutan argumen penting, banyak.
Argumen dapat berupa opsi, tes, dan tindakan. Anda biasanya harus menggunakan opsi terlebih dahulu, lalu menguji, lalu bertindak.
Kadang find
- kadang bahkan memperingatkan Anda tentang kemungkinan pemesanan yang buruk (misalnya ketika Anda menggunakan -maxdepth
setelah argumen lain), tetapi yang lain tampaknya tidak.
Apa yang find . -delete -name '*ar'
dilakukan adalah:
Apa yang mungkin ingin Anda lakukan adalah:
find -name '*ar' -delete
Ini akan, untuk setiap file, melihat apakah itu cocok '*ar'
, dan hanya jika memenuhi syarat itu akan menghapus file.
Maaf jika Anda tahu terlambat.