我可以使用哪个命令列出以字母开头的所有命令g
?假设我无法使用bash
完成功能,并且必须编写脚本。
答案1
您基本上需要遍历列出的所有目录PATH
并运行 afind
来搜索模式,在本例中,是以字母开头的二进制文件'G'。赶紧跑:
for i in $(echo $PATH | tr ":" "\n")
do
find ${i} -iname "g*" 2> /dev/null
done
值得一提的是,某些目录可能没有一个与正则表达式匹配的文件,因此您必须使用2> /dev/null
.
这种方法对于许多其他情况很有用,例如搜索静态或动态库。
答案2
那里是您可以使用一个简单的命令来执行此操作,但它可能违反了“不使用完成”bash
的要求。bash
尽管如此,我还是将其包含在这个答案的末尾。相反,我将使用几个循环来解决这个问题。
假设您想要g
在以下列出的任何目录中查找以该字母开头的所有可执行外部命令$PATH
:
#!/bin/sh
IFS=:; set -f; set -- $PATH; set +f
for dirpath do
for pathname in "$dirpath"/g*; do
if [ -x "$pathname" ]; then
printf 'Executable: %s (%s)\n' "${pathname##*/}" "$pathname"
fi
done
done
这首先将位置参数设置为变量中保存的目录列表PATH
。它通过设置IFS
为来做到这一点:
。这意味着当我们使用不带引号时,它的值将在字符串中的 - 字符$PATH
上分割。:
为了安全地使用不带引号的变量,我们还set -f
暂时关闭通配符,以防字符串的任何部分可以解释为文件名通配模式。我们再次启用了通配符,set +f
因为稍后我们需要它。
一旦我们将位置参数设置为目录路径列表,我们就会迭代这些参数。在每次迭代中,我们获取该目录中以该字母开头的所有文件的路径名g
,并测试每个文件以查看它是否 1) 存在,以及 2) 是否可执行(测试-x
执行这两件事)。如果它是可执行的,我们输出它的名称和完整路径名。
请注意,这将问题限制为仅涵盖当前$PATH
.它不会找到别名或 shell 函数。仅作为内置实用程序提供的实用程序也不会被考虑。
使用一个能够理解${variable//pattern/word}
在变量值中的任何位置用字符串替换模式的 shell,并且使用一个find
知道-maxdepth
and 的shell -executable
(值得称赞)以撒在其他地方提到这种方法):
(
set -f
find -H -- ${PATH//:/ } -maxdepth 1 -type f -name 'g*' -executable
)
这将关闭find
命令的通配符,然后搜索列出的每个目录以查找$PATH
与g
可执行文件对应的任何名称开头的名称。这将发现只能由当前用户执行。使用-perm -o+x
代替来-executable
测试可执行位是否设置为“其他”。
-H
的选项将find
使其解析命令行上给出的符号链接(即搜索路径),但不解析遍历路径时找到的符号链接。
以上是一个通用的/bin/sh
解决方案。如果允许使用特殊bash
命令,您可以生成所有外部命令、shell 函数和别名的列表,这些命令以字母g
开头
compgen -c g
要包含内置命令,请使用
compgen -bc g
...但这可能算作“使用bash
完成”。
compgen
内置命令在手册中有记录bash(1)
。