对于我的脚本,我需要在 中完成块设备/dev
,这样当我这样做时
my_script.sh <TAB>
它将完成并为我提供(不在子目录中)/dev/
列出的所有磁盘。/dev
例如:
my_script.sh <TAB>
my_script.sh /dev/
my_script.sh /dev/<TAB>
sda sdb sdc mmcblk0p1
my_script.sh /dev/sd
sda sdb sdc
我应该如何修改我的完成度才能使其按描述工作?
_arguments -S : \
'--foo' \
'--bar' \
'*:file:_files'
答案1
尝试:
_arguments -S : \
'--foo' \
'--bar' \
'*:block devices:(( /dev/*(-%b:t) ))'
(-%b:t)
是一个 glob 限定符,%b
用于选择块设备,-
以便在符号链接解析后进行选择,修饰符:t
仅选择t
这些文件的所有文件。
你可以使用_files
, 和益处例如从着色:
_arguments -S : \
'--foo' \
'--bar' \
'*:block devices:_files -W /dev -g "*(-%b)"'
我们使用-W
的选项在此处_files
指定W
来查找这些文件,但仍然提供 的子目录,/dev
以便您可以在其中找到更多块设备。
如果在 Linux 上,您可以使用
'*:block devices:_files -W /sys/class/block'
或者:
'*:block devices:(( /sys/class/block/*(:t) ))'
仅获取这些块设备的内核名称。
答案2
由于您只查找块设备,因此需要两个单独的步骤:
首先,您需要确定其中哪些特殊的准文件/dev
实际上是块设备。这可以使用 来完成stat
。该命令在 unix 中相当普遍,但如果由于某种原因您的发行版中没有它,您可以使用apt install coreutils
.
以下命令创建一个由 /dev 内找到的块设备(以 800 开头的设备)全名组成的数组
blockdevs=($(stat -c "%t %n" /dev/* | grep "^8" | cut -d' ' -f2))
笔记:如果您正在寻找的不仅仅是实际的块设备(并非所有文件名/dev
都是块设备。除了普通文件和目录之外,还会有“字符特殊文件”,例如各种子类型,例如/dev/tty
和/dev/zero
,或符号链接,例如/dev/core
)需要编辑上面的数组声明。
获得数组后,您可以根据其存储的值创建相应的补全(引号非常重要):
compctl -g "${blockdevs}" my_script.sh
现在,如果您的命令行以 开头my script.sh
并点击TAB,完成器将自动填写/dev/' and then display the names of blockdevices found in the top-most level of that directory (i.e.
/dev/ 的起始前缀。`)。
这种使用数组值的方法适用于所有类型的自定义完成。基本上它所做的就是检查第一个单词是否匹配myscript.sh
,然后如果没有检测到其他输入作为第二个参数,则它匹配并仅显示(:t)
在中找到的文件名(使用修饰符)结果/dev
在终端中执行这两行代码,或者将它们都添加到 ~/.zshrc 以持久保存完成。