Cara menyingkirkan "No match found" saat menjalankan "rm *"

22

Dengan menggunakan zsh, saya mendapatkan pesan "Tidak ditemukan kecocokan" ketika memilih pola yang tidak sesuai rmdan bahkan ketika mengarahkan ulang output.

# rm * > /dev/zero 2>&1
  zsh: no matches found: *

Bagaimana saya bisa menghilangkan pesan ini?

pengguna123456
sumber
Apakah Anda mencoba menghapus semua yang ada di direktori saat ini? Apa direktori saat ini?
cutrightjm
Anda bisa menggunakan setopt extended_glob(atau bahkan polos rm * >/dev/null 2>&1) tetapi sebenarnya Anda harus membuat solusi untuk tidak perlu rm *, itu benar-benar berbahaya
grochmal
Anda harus benar-benar tenggelam /dev/nulldaripada itu dev/zero. Juga, pengarahan ulang stderr Anda tidak memiliki &; seharusnya begitu 2>&1.
roaima
Pesan kesalahan dihasilkan oleh zshselama evaluasi perintah dan bukan selama runtime dari perintah itu sendiri (karena kesalahan perintah bahkan tidak dijalankan). Pengalihan output di sini hanya akan mempengaruhi output dari perintah dan bukan shell itu sendiri.
Adaephon

Jawaban:

42

Perilaku ini dikendalikan oleh nomatchopsi Zsh . Secara default, jika baris perintah berisi ekspresi globbing yang tidak cocok dengan apa pun, Zsh akan mencetak pesan kesalahan yang Anda lihat, dan tidak menjalankan perintah sama sekali. Anda dapat menonaktifkan ini dengan menjalankan

setopt +o nomatch

Kemudian, globbing ekspresi yang tidak cocok dengan apa pun akan dibiarkan apa adanya, dan Anda akan mendapatkan pesan kesalahan dari rm(yang dapat Anda nonaktifkan menggunakan -f, meskipun itu adalah ide yang buruk karena akan memaksa pemindahan dalam situasi lain di mana Anda mungkin tidak ingin).

Stephen Kitt
sumber
4
Perilaku juga dikendalikan oleh opsi nullglobdan cshnullglob. Jika nullglobdiatur dan tidak ada file yang cocok ditemukan, polanya dihapus dari daftar argumen alih-alih menghasilkan kesalahan. Pengaturan cshnullglobmemiliki efek yang sama kecuali semua pola dalam perintah tidak cocok, dalam hal ini kesalahan akan dilaporkan. Catatan: pengaturan nullglobatau cshnullglobpenggantian nomatch. Anda juga dapat mengatur nullglobpola tunggal dengan menggunakan kualifikasi gumpal N: rm *(N).
Adaephon
nomatchkurang dari ideal, itulah yang dilakukan kerang mirip Bourne. Jika pola tidak cocok, diteruskan apa adanya ke rm(!) Yang rmakan memberikan kesalahan, atau lebih buruk lagi dapat menghapus file yang salah untuk pola seperti *.[ch]misalnya!
Stéphane Chazelas
9

Apa yang ingin Anda lakukan? Tidak berjalan rmsama sekali (1)? Jalankan dengan *argumen literal seperti di shell Bourne-like lainnya (2)? Jalankan tanpa argumen sama sekali (3)?

  1. files=(*(N)); (($#files)) && rm -- $files. Atau (rm -- *) 2> /dev/nulltapi itu juga akan menyembunyikan kesalahan asli rmyang konyol. Anda bisa membuang zshkesalahan tetapi mengembalikan stderr untuk rmperintah dengan(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null. Kemudian seperti shyang zshsekarang ditiru untuk baris perintah tunggal, yang tidak cocok *diteruskan apa adanya rmdan rmmengeluh karena *file itu tidak ada. Kami menekan rmstderr seperti yang Anda lakukan shuntuk menekan pesan kesalahan itu, tetapi sekali lagi, itu konyol karena akan menyembunyikan kesalahan asli dengan rmbertentangan dengan kesalahan yang ditimbulkan oleh kelakuan buruk dari shmenyampaikan literal *ke rm. rm -f '*'tidak akan mengeluh tentang *file yang tidak ada , jadi Anda bisa melakukannyaemulate sh -c 'rm -f -- *'
  3. rm -- *(N). rmakan mengeluh meskipun ketika tidak lulus argumen, meskipun lagi, tidak rm -f: rm -f -- *(N).

Secara umum, rm -fadalah perintah yang ingin Anda gunakan jika Anda ingin semua file hilang dan hanya mendapatkan kesalahan jika file tidak dapat dihapus atau TKI masih ada setelah rmkembali. Anda juga umumnya ingin menggunakan -fskrip untuk menghindari pengguna diminta dalam beberapa situasi.

Di sini, menelepon rmsaat glob tidak cocok adalah salah. The sh1 perilaku yang salah. Ini tidak berbahaya untuk pola seperti *, tetapi untuk yang seperti *.[ch], melewati *.[ch]apa adanya ketika tidak cocok dapat menyebabkan *.[ch]file dihapus secara tidak sengaja:

$ ls
*.[ch]  foo.txt
$ zsh -c 'rm *.[ch]'
zsh:1: no matches found: *.[ch]
$ ls
*.[ch]  foo.txt
$ sh -c 'rm *.[ch]'
$ ls
foo.txt

Gagal dengan kesalahan adalah hal yang masuk akal yang paling harus dilakukan dan apa zsh(dan fish, csh, tcsh, bash -o failglobdan yang asli Unix shell) tidak.

Dan jika Anda ingin menjaga diri Anda sendiri dari kasus khusus itu, zshmembuatnya mudah dengan (N)kualifikasi glob (untuk noglob ) seperti dalam kasus (1) di atas. fish(setidaknya dalam versi terbaru ) membuatnya lebih mudah karena ia melakukan noglob implisit untuk setperintah. Jadi, yang setara di sana, adalah:

set files *
if count $files > /dev/null
  rm -f -- $files
end

Lihat Mengapa nullglob tidak default untuk detail lebih lanjut.


1 . Sebenarnya itu baru shsejak shell Bourne (sejak Unix V7 pada 1979); versi sebelumnya dari sh(yang memang memanggil /etc/globwildcard yang tidak dikutip dari mana nama glob berasal) berperilaku seperti cshatau zsh -o cshnullglob, yaitu /etc/globakan membatalkan perintah jika tidak ada gumpalan yang cocok (dan akan menekan gumpalan yang tidak cocok jika setidaknya salah satu dari mereka punya kecocokan). Perilaku itu rusak oleh kulit Bourne.

Stéphane Chazelas
sumber
Saya pikir dia mengharapkan untuk mendapatkan pesan kesalahan dari rmdan bukan dari shell. Sesuatu seperti "rm: tidak dapat menghapus` * ': Tidak ada file atau direktori ".
Emmanuel
@ Emmanuel, maka itu 2: emulate sh -c 'rm -- *'untuk mendapatkan perilaku (kereta IMO) dari shell Bourne.
Stéphane Chazelas
@Stephane_Chazelas seperti yang tertulis, 2 adalah jawaban yang tepat untuk pertanyaan yang tidak dia tanyakan :).
Emmanuel
@ Emmanuel, ketiga menjawab pertanyaan: bagaimana cara menyingkirkan kesalahan "Tidak cocok". Kode OP menekan rmkesalahan. Itu sesuatu yang akan Anda lakukan di shell lain untuk menekan kesalahan ketika tidak ada file yang cocok dan yang menyebabkan penindasan kesalahan rm asli juga. Jawaban saya menguraikan itu dan mudah-mudahan menunjukkan bagaimana perilaku zsh lebih disukai.
Stéphane Chazelas