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

Alb*_*gni 5 bash

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

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

它删除所有文件和目录,但删除命令行上命名的文件和目录.

你能解释一下:

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

Pau*_*ce. 4

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

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

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

rmbut a b c
Run Code Online (Sandbox Code Playgroud)

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

认为该功能可以简化为:

rmbut() { 
    IFS= rm -rf *[!"$*"] 
}
Run Code Online (Sandbox Code Playgroud)

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