Список усіх файлів / двійкових файлів у поточному PATH


10

Чи існує "простий" спосіб виконання команди "ls-la" для переліку всіх файлів / виконуваних бінарних файлів у поточному PATH?

(Я маю намір передати висновок в grep, для пошуку команд з невідомими префіксами, але в основному відомими "іменами", такий випадок, коли автоматичне завершення / вкладка в bash по суті є марним. Отже, якась "обернена авто- повна функція "...)


Чи можете ви навести приклади? Як буде по-іншому ls -la?
Джон Сіу

"ls -la" / "ls -a" містить лише список файлів у вашому поточному каталозі (pwd). Я хочу перерахувати всі (виконувані) файли у всіх каталогах, включених до PATH.
смі

Відповіді:


19
compgen -c # will list all the commands you could run.
compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go. 

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

Добре працює ... в баш.
Емануель Берг

чи є спосіб перелічити шлях кожного з них, не роблячи цього which $(compgen -A function -abck)?
h3rrmiller

Не вдалося знайти кращої альтернативи.
Нікакін

3

Ось функція, яка перераховує вміст каталогів $PATH. Якщо передані аргументи, функція містить лише команди, ім'я яких містить один з аргументів. Аргументи трактуються як глобальні зразки.

shopt -s extglob
lspath () {
  local IFS pattern
  IFS='|'
  pattern="*@($*)*"
  IFS=':'
  for d in $PATH; do
    for x in "$d/"$pattern; do
      [ "$x" = "$d/$pattern" ] || echo "${x##*/}"
    done
  done | sort -u
}

Як і багато речей, в zsh це простіше.

lspath () {
  (($#)) || set ''
  print -lr -- $^path/*$^@*(N:t) | sort -u
}

^Символ в розкладанні параметра призводить текст зчіплюються з масивом , які будуть додані до кожного елементу масиву, наприклад , path=(/bin /usr/bin); echo $^path/fooвідбитки /bin/foo /usr/bin/foo.
/*$^@*виглядає як образа коміксів, але насправді є звичайним персонажем /, символом підстановки *, спеціальним параметром $@(масивом позиційного параметра) з ^модифікатором і знову *.
(N:t)є глобальним класифікатором N для отримання порожнього розширення, якщо немає відповідності, за яким модифікатор історії t зберігає лише базове ім'я ("хвіст") кожного матчу.

Більш криптовалюта, уникає зовнішнього дзвінка, але це лише для косметичного інтересу:

lspath () {
  (($#)) || set ''
  local names; names=($^path/*$^@*(N:t))
  print -lr -- ${(ou)names}
}

Насправді ви можете шукати aproposкоманду, яка шукає довідні сторінки команд, короткий опис яких містить ключове слово. Обмеження полягає в тому, що це знаходять лише команди, які мають довідкову сторінку.


У функції zsh, ^здається , що другий не призводить до виходу без виклику "без аргументів"? Якщо ви скасуєте його, ви можете перелічити їх усіх і все одно шукати окремі ключові слова (але не їх список). (Non:t)Здається, що зірочки слід розширити? Не вдалося розібратися з останнім.
Емануель Берг

@EmanuelBerg Правильно, дякую за виправлення. Я додав пояснення лінійного шуму.
Жил "ТАК - перестань бути злим"

Гаразд, подивимось: якщо аргументів немає, ви встановлюєте їх "ні до чого", тому що те, що там було (коли їх не було), все одно якось порушує те, що ви робили далі? Крім того, я ніколи не бачив малі літери path, але коли я запускаю його в оболонці, це дійсно $ PATH, але замість пробілів :. Решта - чисто кришталево :)
Емануель Берг

@EmanuelBerg Ні: якщо аргументів немає, я встановлюю масив аргументів як одноелементний масив, що містить порожній рядок. Таким чином, жодні аргументи не означають, що кожне ім’я містить відповідність порожніх рядків, тобто кожне ім'я відповідає. $pathє функцією zsh: це прив'язаний параметр , масив, який автоматично оновлюється, коли PATHоновлюється, і навпаки.
Жил "ТАК - перестань бути злим"

Ага, тепер я бачу! Ого, це було неортодоксально!
Емануель Берг

1
function findinpath () { 
   OLDIFS="$IFS" ; 
   IFS="$(printf ':\t\n')" ; 
   for regexp in "$@" ; do 
      for adir in $PATH ; do 
         find "$adir" -perm -111 -a ! -type d -ls 2>/dev/null | grep -i "/[^/]*$regexp"
      done ; 
   done ; 
   IFS="$OLDIFS" ; 
}

знайти лише відповідність, у якій встановлено принаймні один біт "x" (виконується), і це не каталог.

і використовуйте його зі списком регулярного вираження, який потрібно знайти:

findinpath awk sed '\.sh$'

regexp "." покаже вам все
Олів'є Дулак

за допомогою звичайних IFS ви можете знайти повторювані записи у вашому $ PATH за допомогою:echo $PATH | tr ':' '\n' | sort | uniq -d
Олів'є Дулака,

1
Я спробував код для всіх відповідей, і це єдиний, який насправді дав мені те, що я шукав (повний шлях до кожного екземпляра заданої команди на PATH).
Кріс

Я радий, що це допомогло :)
Олів'є Дулак

1
for i in $(echo $PATH | sed -e 's/\:/\ /g'); do find "$i" -perm +rwx -exec echo {} \; 2> /dev/null; done

спочатку ми перегукуємося $PATHз sed і замінюємо ":" на "".

то ми робимо знахідку по кожному з цих речей, щоб знайти файли з rwx та повторювати їх.

2> /dev/nullтому findне буде друкувати помилки


3
вам знадобиться -maxdepth 1і -type fу вашій знаходженні, інакше ви знайдете підкаталоги та їх файли (які PATH пошук не буде). Крім того, ваш тест на дозвіл є дивним - +xя маю на увазі, саме для цього?
дероберт

Це не буде обробляти крайові регістри, якщо дійсний порожній запис такий самий, як ".", Наприклад :/binабо /bin::/usr/bin. Спробуйте додати s/::/:.:/;s/^:/.:/;s/:$/:./до sedкоманди.
Арседж

Насправді findможна шукати більше шляхів, тому ви можете робити це без циклу: find $(echo $PATH | sed -e 's/\:/\ /g') -perm +rwx …Звичайно, імена каталогів, що містять пробіли, зіпсують це, але на основі циклу у будь-якого випадку є така ж проблема.
манатство

@manatwork ти маєш рацію. Я додав цитати, щоб вирішити цю проблему зараз
h3rrmiller

Вибачте, що нічого не вирішує. Проблема полягає в заміні колонок пробілами, щоб дозволити поділ слів. Отже, ви перетворюєте "/ foo bar: / fiz baz" в "/ foo bar / fiz baz", після чого передаєте це for. Так forбуде переведено список із 4-х слів. Для того, щоб маніпулювати словом Розщеплення краще встановити в IFSвідповідно до ваших потреб: IFS=':'; find $PATH -perm +rwx ….
манатство
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.