想列出目录里所有“.tmp”结尾的文件,很自然就会想到“ls *.tmp”,觉得ls就是干这个用的。到最近才忽然明白,这样做虽然能达到目(通常情况下),但实际并不是这么回事!
启发我的问题是这样的。当时目录里充满的垃圾文件,我用rm去删除,“rm *.tmp”,但是根本不起作用,shell提示说命令行超长了。bash的命令行最大长度是4096byte。当输入“rm *.tmp”时,bash会先进行通配符展开。把“*.tmp”展开,也就是把所有“.tmp”文件的文件名链接到“rm”后面。一旦文件有多,文件名又长,整个命令行就超标了,bash拒绝接受!
解决问题的方法:
- echo *.tmp | xargs rm
- find –name '*.tmp' –delete
要注意的是,“rm *.tmp”和“echo *.tmp | xargs rm”不会删除“.tmp”的子目录,删子目录需要“-r”,而find会删除子目录,除非加上“-type f”参数。
对于“echo *.tmp | xargs rm”,我还是有疑问的。难道echo *.tmp就不会有通配符展开的问题了吗?不知道,echo是bash内建的命令,而且反正echo也是把匹配的文件名写出来而已,也许真的不用展开。
好了,现在回到“ls *.tmp”的话题上来。和上面一样,命令执行时先通配符展开——好了,实际上我要做的事情并不是ls做的,而是bash,通配符展开的时候“.tmp”文件就已经被bash找出来了。最终执行的命令应该象是这样“ls 1.tmp 2.tmp 3.tmp … …”。
没有评论:
发表评论