您要它做什么呢?根本不运行rm
(1)?与*
其他类似Bourne的shell(2)中一样,使用文字参数来运行它吗?完全不带参数运行(3)?
files=(*(N)); (($#files)) && rm -- $files
。或者,(rm -- *) 2> /dev/null
但这也将隐藏真正的错误,rm
而这将是愚蠢的。您可以丢弃zsh
错误,但可以通过以下rm
命令恢复命令的stderr(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
emulate sh -c 'rm -- *' 2> /dev/null
。然后像在sh
其zsh
现在模拟为单个命令行中,非匹配*
原样传递是rm
和rm
抱怨作为*
文件不存在。我们抑制了rm
stderr,就像sh
抑制该错误消息一样,但是这又很愚蠢,因为它将隐藏真正的错误,rm
,而不是通过的不当行为引起的误差sh
通过文字*
来rm
。rm -f '*'
不会抱怨*
文件不存在,所以您可以emulate sh -c 'rm -f -- *'
rm -- *(N)
。rm
可能会抱怨,尽管没有传递任何参数,但不是rm -f
:rm -f -- *(N)
。
通常,rm -f
如果您希望所有文件都消失,并且仅在无法删除文件或rm
返回后IOW仍然存在的情况下才会出现错误,则是您要使用的命令。您通常也想使用-f
在脚本中,以避免在某些情况下提示用户。
在这里,rm
当全局不匹配时调用是错误的。在sh
1层的行为是错误的。对于类似的模式*
,这是无害的,但是对于类似的模式,当不匹配时按原样*.[ch]
传递*.[ch]
可能会导致*.[ch]
文件被错误地删除:
$ 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
与错误而失败是做的最明智的事情,是什么zsh
(和fish
,csh
,tcsh
,bash -o failglob
和原来的Unix shell)一样。
而且,如果您想保管这种特殊情况,zsh
可以像上面的情况(1)一样,使用其(N)
glob限定符(对于noglob)使其变得容易。fish
(至少在最新版本中),因为它执行隐式的noglob使其更加容易为set
命令。因此,等效项为:
set files *
if count $files > /dev/null
rm -f -- $files
end
请参阅为什么nullglob不是默认值更多详细信息,。
1。严格来说,这只是sh
自Bourne shell以来(自1979年Unix V7起)。的早期版本sh
(确实调用/etc/glob
了无引号的通配符,这是通配符名称所来自的地方)的行为类似csh
或zsh -o cshnullglob
,/etc/glob
如果所有通配符都不匹配,它将中止命令(并且至少抑制不通配的通配符)其中之一有任何比赛)。该行为被Bourne外壳破坏了。