Dengan menggunakan zsh
, saya mendapatkan pesan "Tidak ditemukan kecocokan" ketika memilih pola yang tidak sesuai rm
dan bahkan ketika mengarahkan ulang output.
# rm * > /dev/zero 2>&1
zsh: no matches found: *
Bagaimana saya bisa menghilangkan pesan ini?
setopt extended_glob
(atau bahkan polosrm * >/dev/null 2>&1
) tetapi sebenarnya Anda harus membuat solusi untuk tidak perlurm *
, itu benar-benar berbahaya/dev/null
daripada itudev/zero
. Juga, pengarahan ulang stderr Anda tidak memiliki&
; seharusnya begitu2>&1
.zsh
selama 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.Jawaban:
Perilaku ini dikendalikan oleh
nomatch
opsi 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 menjalankanKemudian, 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).sumber
nullglob
dancshnullglob
. Jikanullglob
diatur dan tidak ada file yang cocok ditemukan, polanya dihapus dari daftar argumen alih-alih menghasilkan kesalahan. Pengaturancshnullglob
memiliki efek yang sama kecuali semua pola dalam perintah tidak cocok, dalam hal ini kesalahan akan dilaporkan. Catatan: pengaturannullglob
ataucshnullglob
penggantiannomatch
. Anda juga dapat mengaturnullglob
pola tunggal dengan menggunakan kualifikasi gumpalN
:rm *(N)
.nomatch
kurang dari ideal, itulah yang dilakukan kerang mirip Bourne. Jika pola tidak cocok, diteruskan apa adanya kerm
(!) Yangrm
akan memberikan kesalahan, atau lebih buruk lagi dapat menghapus file yang salah untuk pola seperti*.[ch]
misalnya!Apa yang ingin Anda lakukan? Tidak berjalan
rm
sama sekali (1)? Jalankan dengan*
argumen literal seperti di shell Bourne-like lainnya (2)? Jalankan tanpa argumen sama sekali (3)?files=(*(N)); (($#files)) && rm -- $files
. Atau(rm -- *) 2> /dev/null
tapi itu juga akan menyembunyikan kesalahan aslirm
yang konyol. Anda bisa membuangzsh
kesalahan tetapi mengembalikan stderr untukrm
perintah dengan(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Kemudian sepertish
yangzsh
sekarang ditiru untuk baris perintah tunggal, yang tidak cocok*
diteruskan apa adanyarm
danrm
mengeluh karena*
file itu tidak ada. Kami menekanrm
stderr seperti yang Anda lakukansh
untuk menekan pesan kesalahan itu, tetapi sekali lagi, itu konyol karena akan menyembunyikan kesalahan asli denganrm
bertentangan dengan kesalahan yang ditimbulkan oleh kelakuan buruk darish
menyampaikan literal*
kerm
.rm -f '*'
tidak akan mengeluh tentang*
file yang tidak ada , jadi Anda bisa melakukannyaemulate sh -c 'rm -f -- *'
rm -- *(N)
.rm
akan mengeluh meskipun ketika tidak lulus argumen, meskipun lagi, tidakrm -f
:rm -f -- *(N)
.Secara umum,
rm -f
adalah perintah yang ingin Anda gunakan jika Anda ingin semua file hilang dan hanya mendapatkan kesalahan jika file tidak dapat dihapus atau TKI masih ada setelahrm
kembali. Anda juga umumnya ingin menggunakan-f
skrip untuk menghindari pengguna diminta dalam beberapa situasi.Di sini, menelepon
rm
saat glob tidak cocok adalah salah. Thesh
1 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:Gagal dengan kesalahan adalah hal yang masuk akal yang paling harus dilakukan dan apa
zsh
(danfish
,csh
,tcsh
,bash -o failglob
dan yang asli Unix shell) tidak.Dan jika Anda ingin menjaga diri Anda sendiri dari kasus khusus itu,
zsh
membuatnya 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 untukset
perintah. Jadi, yang setara di sana, adalah:Lihat Mengapa nullglob tidak default untuk detail lebih lanjut.
1 . Sebenarnya itu baru
sh
sejak shell Bourne (sejak Unix V7 pada 1979); versi sebelumnya darish
(yang memang memanggil/etc/glob
wildcard yang tidak dikutip dari mana nama glob berasal) berperilaku seperticsh
atauzsh -o cshnullglob
, yaitu/etc/glob
akan 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.sumber
rm
dan bukan dari shell. Sesuatu seperti "rm: tidak dapat menghapus` * ': Tidak ada file atau direktori ".emulate sh -c 'rm -- *'
untuk mendapatkan perilaku (kereta IMO) dari shell Bourne.rm
kesalahan. 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.