Mengapa rm * (1) * menghapus semua file dalam direktori?

47

Saya berharap bahwa:

$ rm *(1)*

akan menghapus semua file yang mengandung (1)nama. Saya salah. Itu menghapus semua file di direktori.

Mengapa?

Eric Wilson
sumber
5
Setiap kali saya menggunakan rmsuatu pola, saya selalu mendahului dengan echosebelum mengeluarkan perintah yang sebenarnya. Kebiasaan itu menyelamatkan saya lebih dari sekali (sejak itu, ketika berusia 6 tahun, membingungkan perbedaan antara DEL A: *.*dan DEL *.* A:).
gerrit

Jawaban:

51

Dari man bash:

*(pattern-list)
                 Matches zero or more occurrences of the given patterns

Anda memiliki ekspresi glob yang cocok dengan file yang dimulai dengan nol atau lebih 1- yang semuanya file.

Salah satu cara sederhana untuk menonaktifkan perilaku globbing ini adalah dengan \keluar dari tanda kurung:

rm *\(1\)*

Jika tidak, Anda dapat menggunakan shopt -u extglobuntuk menonaktifkan perilaku dan shopt -s extglobmengaktifkannya kembali:

shopt -u extglob
rm *(1)*
shopt -s extglob

Perhatikan bahwa sebagaimana dikatakan Stephane , extglobdiaktifkan dengan bash-completionmenonaktifkannya dapat menyebabkan fungsi penyelesaian tidak berfungsi dengan benar.

Graeme
sumber
7
Catatan yang extglobtidak aktif secara default tetapi dihidupkan oleh bash_completion jika Anda telah menginstal dan mengaktifkannya. bashtidak memiliki cakupan lokal untuk opsi seperti zshhalnya.
Stéphane Chazelas
1
Perhatikan juga bahwa bash-4.3memiliki regresi yang *(1)*juga memperluas file tersembunyi.
Stéphane Chazelas
@StephaneChazelas Apakah Anda memiliki tautan untuk bug yang berkaitan dengan regresi itu? Terima kasih
Dasar
2
@Basic, ini dia . Chet belum menjawab.
Stéphane Chazelas
9

Ini mungkin terkait dengan extglobopsi shell. Jika saya mematikannya, pola menghasilkan pesan kesalahan:

martin@dogmeat:~$ shopt -u extglob
martin@dogmeat:~$ shopt extglob
extglob         off
martin@dogmeat:~$ echo *(1)*
bash: syntax error near unexpected token `('

Jika saya menyalakannya, sepertinya cocok dengan semuanya. Manual mendokumentasikan pola-pola ini, saya pikir mereka terkait:

   If the extglob shell option is enabled using the shopt builtin, several
   extended  pattern  matching operators are recognized.  In the following
   description, a pattern-list is a list of one or more patterns separated
   by a |.  Composite patterns may be formed using one or more of the fol
   lowing sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns

Saya tidak melihat dokumentasi yang menentukan apa yang dilakukan kurung tanpa karakter utama. Bagaimanapun, Anda dapat menghindari masalah dengan mengutip parens:

martin@dogmeat ~ % echo *\(1\)*
A(1)b

Juga, gunakan echoatau lsuntuk menguji pola Anda terlebih dahulu jika Anda tidak benar-benar yakin itu berhasil :)

Martin von Wittich
sumber
FYI: {adalah penjepit, (adalah paren (atau braket bulat).
Mikel
Ah terima kasih. Saya bukan penutur asli bahasa Inggris jadi saya cenderung membingungkan mereka :)
Martin von Wittich
6
Di Inggris: {= braket keriting, (= braket bulat, [= braket persegi. Di Amerika: {= brace, (= paren, [= braket. Agak membingungkan. Jika Anda perlu memeriksa apa yang disebut sesuatu, File Jargon - ASCII cukup membantu.
Mikel
4
@ Kemungkinan Terima kasih, saya juga memeriksa di sini jadi sekarang saya tahu tentang kurung bunga dan yang tupai !
Dalam bahasa Inggris India, {adalah braket bunga, [braket persegi, dan (braket bulat atau lebih sering hanya braket. :-)
ShreevatsaR