Thay vào đó, bạn muốn nó làm gì? Không chạy rm
chút nào (1)? Chạy nó với một *
đối số theo nghĩa đen như trong các shell giống như Bourne khác (2)? Chạy nó không có đối số nào cả (3)?
files=(*(N)); (($#files)) && rm -- $files
. Hoặc (rm -- *) 2> /dev/null
nhưng điều đó cũng sẽ che giấu các lỗi chính hãng rm
mà sẽ là ngớ ngẩn. Bạn có thể loại bỏ zsh
lỗi nhưng khôi phục stderr cho rm
lệnh mặc dù với(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
. Sau đó, giống như trong sh
đó zsh
bây giờ được mô phỏng cho dòng lệnh đơn lẻ đó, việc không khớp *
được truyền theo nguyên trạng rm
và rm
phàn nàn vì *
tệp đó không tồn tại. Chúng ngăn chặn rm
's stderr như bạn sẽ làm gì trong sh
để ngăn chặn điều đó thông báo lỗi, nhưng một lần nữa, đó là ngớ ngẩn vì nó sẽ che giấu lỗi chính hãng bởi rm
như trái ngược với các lỗi phát sinh do hành vi sai trái của sh
đi qua một nghĩa đen *
đến rm
. rm -f '*'
sẽ không phàn nàn về một *
tập tin chưa tồn tại , vì vậy bạn có thể làmemulate sh -c 'rm -f -- *'
rm -- *(N)
. rm
sẽ khiếu nại mặc dù khi không thông qua bất kỳ đối số, mặc dù một lần nữa, không rm -f
: rm -f -- *(N)
.
Nói chung, rm -f
là lệnh bạn muốn sử dụng nếu bạn muốn tất cả các tệp biến mất và chỉ gặp lỗi nếu không thể xóa các tệp hoặc IOW vẫn còn đó sau khi rm
đã trả về. Bạn cũng thường muốn sử dụng -f
trong các tập lệnh để tránh người dùng bị nhắc nhở trong một số tình huống.
Ở đây, gọi rm
khi toàn cầu không khớp là sai. Các sh
1 hành vi là sai. Nó vô hại đối với một kiểu như *
, nhưng đối với một lượt thích *.[ch]
, việc chuyển qua trạng thái *.[ch]
không khớp có thể khiến *.[ch]
tệp bị xóa do nhầm lẫn:
$ 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
Không có một lỗi là điều hợp lý nhất để làm và là những gì zsh
(và fish
, csh
, tcsh
, bash -o failglob
và bản gốc Unix shell) does.
Và nếu bạn muốn tự chăm sóc cho trường hợp đặc biệt đó, hãy zsh
làm cho nó dễ dàng với (N)
vòng loại toàn cầu của nó (đối với noglob ) như trong trường hợp (1) ở trên. fish
(ít nhất là trong phiên bản gần đây ) làm cho nó thậm chí còn dễ dàng hơn khi nó thực hiện một noglob ngầm cho set
lệnh. Vì vậy, tương đương ở đó, sẽ là:
set files *
if count $files > /dev/null
rm -f -- $files
end
Xem Tại sao nullglob không được mặc định để biết thêm chi tiết.
1 . Nói một cách chính xác, đó chỉ là sh
từ vỏ Bourne (kể từ Unix V7 năm 1979); phiên bản trước của sh
(mà đã gọi /etc/glob
theo ký tự đại diện không thể viện chứng đó là nơi mà các glob tên xuất phát từ) đã hành xử giống như csh
hoặc zsh -o cshnullglob
, có nghĩa là /etc/glob
sẽ hủy bỏ lệnh nếu không có những đống có bất kỳ trận đấu (và sẽ ngăn chặn những đống không phù hợp nếu có ít nhất một trong số họ đã có bất kỳ trận đấu). Hành vi đã bị phá vỡ bởi vỏ Bourne.