bash: получить список команд, начинающихся с заданной строки - PullRequest
15 голосов
/ 04 февраля 2009

Можно ли с помощью Bash получить список команд, начинающихся с определенной строки?
Я хотел бы получить напечатанное, дважды нажав после ввода начала команды и, например, сохранить его внутри переменной.

Ответы [ 8 ]

33 голосов
/ 04 февраля 2009

Вы должны использовать команду compgen , например:

compgen -A builtin [YOUR STRING HERE]

Например, «compgen -A builtin l» возвращает

let 
local 
logout

Вы можете использовать другие ключевые слова вместо «встроенные», чтобы получить другие типы завершения. Встроенный дает вам встроенные команды оболочки. «Файл» дает вам локальные имена файлов и т. Д.

Вот список действий (из справочной страницы BASH для complete , которая использует 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
                 -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.
2 голосов
/ 06 февраля 2009

Забавный способ сделать это - нажать M-* (мету обычно оставляют Alt).

Например, введите это:

$ 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.

1 голос
/ 04 февраля 2009

Интересно, я не знал о 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
1 голос
/ 04 февраля 2009

Якоб М ответ велик. Чтобы сделать это вручную, я бы использовал что-то вроде этого:

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

Проверка перед выводом показывает, что отображаются только исполняемые, обычные файлы. Выше показаны все команды, начинающиеся с mod.

1 голос
/ 04 февраля 2009

Если вы хотите точно, как завершится bash

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

compgen завершает работу по тем же правилам, которые использует bash при добавлении табуляции.

0 голосов
/ 04 февраля 2009

Просто для удовольствия, другой ручной вариант:

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

подберет файлы, на которые у вас есть разрешение, в силу их владения. Я не вижу общего способа получить все, что вы можете выполнить с помощью групповой принадлежности, без гораздо большего кодирования.

0 голосов
/ 04 февраля 2009

Когда вы нажимаете, в списке отображаются двоичные файлы, которые начинаются с этой строки. Итак, если ваша переменная PATH содержит: PATH = / USR / местные / бен: / USR / бен: / бен: / USR / игры: / USR / Lib / Java / бен: / USR / Lib / Java / JRE / бен: / USR / Lib / кварты / бен : / USR / доли / TEXMF / бен:.

Bash будет смотреть в каждом из этих каталогов, чтобы показать вам предложения, как только вы нажмете. Таким образом, чтобы получить список команд, начинающихся с «ls», в переменную, вы можете сделать: MYVAR = $ (ls / usr / local / bin / ls * / usr / bin / ls * / bin / ls *) Естественно, вы можете добавить все остальные каталоги, которых у меня нет.

0 голосов
/ 04 февраля 2009

Переберите переменную $ PATH и выполните ls beginningofword* для каждого каталога в пути?

Чтобы получить его в точности эквивалентно, вам нужно отфильтровать только исполняемые файлы и отсортировать по имени (должно быть довольно просто с помощью флагов ls и команды sort).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...