有没有可能用Bash获得以某个字符串开头的命令列表?
I would like to get what is printed hitting <tab> twice after typing the start of the command and, for example, store it inside a variable.

linux
bash
scripting
Paolo Tedesco
Paolo Tedesco
发布于 2009-02-04
8 个回答
Jacob Mattison
Jacob Mattison
发布于 2009-02-04
已采纳
0 人赞同

你应该能够使用 compgen 命令,像这样。

compgen -A builtin [YOUR STRING HERE]

例如,"compgen -A builtin l "会返回

local logout

你可以用其他关键字代替 "buildin "来获得其他类型的完成。 Builtin给你提供shell的内置命令。 "File "给出了本地文件名,等等。

下面是一个行动列表(来自BASH手册页的complete which uses compgen):

  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
  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.
    
很好。我在这一点上挣扎过,也完成过,但一直没能想出如何使用它。+1 :)
porges
porges
发布于 2009-02-04
0 人赞同

一个有趣的方法是点击 M-* (Meta通常是左Alt)。

作为一个例子,请输入以下内容。

Then hit 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库的一个特点。

Flame
Flame
发布于 2009-02-04
0 人赞同

如果你想知道bash究竟会如何完成

COMPLETIONS=$(compgen -c "$WORD")

compgen使用与bash在标签时相同的规则来完成。

Johannes Schaub - litb
Johannes Schaub - litb
发布于 2009-02-04
0 人赞同

JacobM的回答很好。对于手动操作,我将使用类似这样的方法。

echo $PATH  | tr : '\n' | 
 while read p; do 
  for i in $p/mod*; do
   [[ -x "$i" && -f "$i" ]] && echo $i     

输出前的测试确保只显示可执行的、正规的文件。上面显示了所有以mod开始的命令。

Adam Rosenfield
Adam Rosenfield
发布于 2009-02-04
0 人赞同

有趣的是,我不知道 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
    
Would this list built-ins?
0 人赞同

只是为了好玩,另一个手动变体。

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

将会拾取你因拥有权限而拥有的文件。我看不出有什么一般的方法可以在不进行更多编码的情况下,获得所有那些你可以凭借集团隶属关系执行的文件。

Oliver N.
Oliver N.
发布于 2009-02-04
0 人赞同

遍历$PATH变量,对路径中的每个目录做 ls beginningofword*

为了得到完全相同的结果,你需要只过滤掉可执行文件,并按名称排序(用ls标志和排序命令应该很容易)。

Eduardo
Eduardo
发布于 2009-02-04
0 人赞同

当你点击时,列出的是你PATH中以该字符串开头的二进制文件。所以,如果你的PATH变量包含