【问题标题】:bash: get list of commands starting with a given stringbash:获取以给定字符串开头的命令列表
【发布时间】:2010-10-05 10:19:51
【问题描述】:

是否可以使用 Bash 获取以某个字符串开头的命令列表?
我想在键入命令的开头后两次点击 来获取打印的内容,例如,将其存储在变量中。

【问题讨论】:

    标签: linux bash scripting


    【解决方案1】:

    您应该能够使用 compgen 命令,如下所示:

    compgen -A builtin [YOUR STRING HERE]
    

    例如,“compgen -A builtin l”返回

    let 
    local 
    logout
    

    您可以使用其他关键字代替“builtin”来获得其他类型的补全。 Builtin 为您提供 shell 内置命令。 “文件”为您提供本地文件名等。

    这是一个操作列表(来自使用 compgencomplete 的 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.
    

    【讨论】:

    • 不错。我为此苦苦挣扎并完成,但无法弄清楚如何使用它。 +1 :)
    • 确实非常有用,而且答案非常好。谢谢! (+1)
    【解决方案2】:

    一个有趣的方法是点击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 库的一个功能。

    【讨论】:

      【解决方案3】:

      如果你想知道 bash 将如何完成

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

      compgen 使用 bash 在 tabbing 时使用的相同规则完成。

      【讨论】:

        【解决方案4】:

        JacobM 的回答很棒。对于手动操作,我会使用这样的东西:

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

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

        【讨论】:

          【解决方案5】:

          有趣,我不知道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
          

          【讨论】:

          • 这个列表会内置吗?
          【解决方案6】:

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

          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
          

          将获取您拥有权限的文件。我没有看到一个通用的方法来获得所有你可以通过组隶属关系执行而不需要更多编码的方法。

          【讨论】:

            【解决方案7】:

            遍历 $PATH 变量并为路径中的每个目录执行ls beginningofword*

            要使其完全等效,您需要仅过滤掉可执行文件并按名称排序(使用 ls 标志和 sort 命令应该很容易)。

            【讨论】:

              【解决方案8】:

              点击时列出的是 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*) 当然,您可以添加我没有添加的所有其他目录。

              【讨论】:

                猜你喜欢
                • 2020-06-25
                • 2018-01-31
                • 2016-12-04
                • 1970-01-01
                • 2013-03-08
                • 1970-01-01
                • 1970-01-01
                • 2011-04-08
                • 2017-02-10
                相关资源
                最近更新 更多