【发布时间】:2010-10-05 10:19:51
【问题描述】:
是否可以使用 Bash 获取以某个字符串开头的命令列表?
我想在键入命令的开头后两次点击
【问题讨论】:
是否可以使用 Bash 获取以某个字符串开头的命令列表?
我想在键入命令的开头后两次点击
【问题讨论】:
您应该能够使用 compgen 命令,如下所示:
compgen -A builtin [YOUR STRING HERE]
例如,“compgen -A builtin l”返回
let
local
logout
您可以使用其他关键字代替“builtin”来获得其他类型的补全。 Builtin 为您提供 shell 内置命令。 “文件”为您提供本地文件名等。
这是一个操作列表(来自使用 compgen 的 complete 的 BASH 手册页):
alias Alias names. May also be specified as -a.
arrayvar Array variable names.
binding Readline key binding names.
builtin Names of shell builtin commands. May also be specified as -b.
command Command names. May also be specified as -c.
directory Directory names. May also be specified as -d.
disabled Names of disabled shell builtins.
enabled Names of enabled shell builtins.
export Names of exported shell variables. May also be specified as -e.
file File names. May also be specified as -f.
function Names of shell functions.
group Group names. May also be specified as -g.
helptopic Help topics as accepted by the help builtin.
hostname Hostnames, as taken from the file specified by the HOSTFILE shell
variable.
job Job names, if job control is active. May also be specified as
-j.
keyword Shell reserved words. May also be specified as -k.
running Names of running jobs, if job control is active.
service Service names. May also be specified as -s.
setopt Valid arguments for the -o option to the set builtin.
shopt Shell option names as accepted by the shopt builtin.
signal Signal names.
stopped Names of stopped jobs, if job control is active.
user User names. May also be specified as -u.
variable Names of all shell variables. May also be specified as -v.
【讨论】:
一个有趣的方法是点击M-*(Meta 通常是左键)。
例如,输入:
$ lo
然后点击M-*:
$ loadkeys loadunimap local locale localedef locale-gen locate
lockfile-create lockfile-remove lockfile-touch logd logger login
logname logout logprof logrotate logsave look lorder losetup
您可以在man 3 readline 中阅读更多相关信息;这是readline 库的一个功能。
【讨论】:
如果你想知道 bash 将如何完成
COMPLETIONS=$(compgen -c "$WORD")
compgen 使用 bash 在 tabbing 时使用的相同规则完成。
【讨论】:
JacobM 的回答很棒。对于手动操作,我会使用这样的东西:
echo $PATH | tr : '\n' |
while read p; do
for i in $p/mod*; do
[[ -x "$i" && -f "$i" ]] && echo $i
done
done
输出前的测试确保只显示可执行的常规文件。以上显示了所有以mod 开头的命令。
【讨论】:
有趣,我不知道compgen。这是我用来执行此操作的脚本,它不检查非可执行文件:
#!/bin/bash
echo $PATH | tr ':' '\0' | xargs -0 ls | grep "$@" | sort
将该脚本保存在您的$PATH(我将其命名为findcmd)、chmod u+w 中的某个位置,然后像grep 一样使用它,传递您最喜欢的选项和模式:
findcmd ^foo # finds all commands beginning with foo
findcmd -i -E 'ba+r' # finds all commands matching the pattern 'ba+r', case insensitively
【讨论】:
只是为了好玩,另一个手动变体:
find -L $(echo $PATH | tr ":" " ") -name 'pattern' -type f -perm -001 -print
其中pattern 指定要使用的文件名模式。这将遗漏不可全局执行但您有权执行的命令。
[在 Mac OS X 上测试]
使用-or 和-and 标志来构建此命令的更全面版本:
find -L $(echo $PATH | tr ":" " ") -name 'pattern' -type f
\( \
-perm -001 -or \
\( -perm -100 -and -user $(whoami)\) \
\) -print
将获取您拥有权限的文件。我没有看到一个通用的方法来获得所有你可以通过组隶属关系执行而不需要更多编码的方法。
【讨论】:
遍历 $PATH 变量并为路径中的每个目录执行ls beginningofword*?
要使其完全等效,您需要仅过滤掉可执行文件并按名称排序(使用 ls 标志和 sort 命令应该很容易)。
【讨论】:
点击时列出的是 PATH 中以该字符串开头的二进制文件。因此,如果您的 PATH 变量包含: PATH=/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib/java/bin:/usr/lib/java/jre/bin:/usr/lib/qt/bin :/usr/share/texmf/bin:.
Bash 将在每个目录中查找,以便在您点击 后向您显示建议。因此,要将以“ls”开头的命令列表放入变量中,您可以执行以下操作: MYVAR=$(ls /usr/local/bin/ls* /usr/bin/ls* /bin/ls*) 当然,您可以添加我没有添加的所有其他目录。
【讨论】: