除了某些文件之外,这个bash函数如何工作?

时间:2011-01-26 13:39:24

标签: bash

我在commandlinefu.com上找到了以下脚本(该示例不再在线):

rmbut() { 
    local x=("$@")
    IFS=, rm -rf *[!"${x[*]}"] 
}

删除所有文件和目录,但删除命令行中命名的文件和目录。

你能解释一下:

  • 第一行发生了什么? $@表示所有参数,但为什么它放在括号内?
  • 我读过IFS但从未真正使用过它,它的用法是什么?
  • *[!"${x[*]}"]取得了什么成果?我无法理解如何将它分成我知道的东西。

2 个答案:

答案 0 :(得分:4)

local x=("$@")创建一个数组,它是所有参数的副本($@本身就是一个数组)。

IFS=,将内部字段分隔符设置为逗号。

IFS=, rm -rf *[!"${x[*]}"]表示删除所有未作为参数传递的字符结尾的文件。由于*用作数组的索引并且引用了变量,因此它将扩展为单个字符串,通常将数组元素分隔的空格将替换为IFS的内容(在这种情况下逗号。)

rmbut a b c

解析为rm -rf *[!a,b,c],这也不会删除以逗号结尾的文件。

认为 该功能可以简化为:

rmbut() { 
    IFS= rm -rf *[!"$*"] 
}

但它的行为会略有不同。此版本将IFS设置为null,因此上面的示例将解析为rm -rf *[!abc] 删除以逗号结尾的文件(逗号必须作为参数显式传递)保存这样的文件)。但是,可以通过设置IFS=,来返回该行为(根本不需要复制数组)。

答案 1 :(得分:3)

#创建一个数组x,包含函数
的参数 local x=("$@")

#取消设置IFS变量。这使得双引号数组扩展为单词w / o分隔符
IFS=

#删除与模式匹配的文件,即不以数组x中的字符结尾 rm -rf *[!"${x[*]}"]