`который`, но все


19

Я думаю, что большинство знакомо с whichкомандой, и я использую ее часто. Я просто столкнулся с ситуацией, когда мне любопытно не только какая команда находится на моем пути первой, но сколько и где все команды на всех моих путях. Я попробовал справочную страницу (печатание man whichзаставило меня смеяться), но ничего не увидел.


1
В моей системе, это первое , что указаны на странице человека: which --all.
Шон Дж. Гофф

2
По моему (linux) это только which -a.
пользователь неизвестен

Ответы:


23

На некоторых системах which -aпоказывает все совпадения. Если ваша оболочка bash или zsh¹, вы можете использовать typeвместо нее : type fooпоказывает первое совпадение и type -a fooпоказывает все совпадения. Три команды type, whichи whenceделают в основном то же самое; они различаются между оболочками и операционными системами по доступности, опциям и что именно они сообщают. typeвсегда доступен и показывает все возможные имена, подобные командам (псевдонимы, ключевые слова, встроенные функции оболочки, функции и внешние команды).

Единственный полностью переносимый способ отобразить все совпадения - это проанализировать $PATHсебя. Вот сценарий оболочки, который делает это. Если вы сделаете это функция оболочки, убедитесь , чтобы приложить тело функции в скобках (так что изменение IFSи set -fне убегают функции), и изменение exitк return.

#!/bin/sh
set -f       # disable globbing
IFS=:        # break words at : only
not_found=1
for d in $PATH; do
  if [ -f "$d/$x" ] && [ -x "$d/$x" ]; then
    printf '%s\n' "$d/$x"
    not_found=0
  fi
done
exit $not_found

¹ Или ksh 93, согласно документации, хотя ksh 93s + 2008-01-31 печатает только первое совпадение, когда я пытаюсь.


Этот shкод не работает должным образом, если в нем есть пустые компоненты $PATH. Также обратите внимание, что $IFSэто разделитель полей (по крайней мере в оболочках POSIX), в то время как $PATHдвоеточие используется в качестве разделителя полей . Смотрите whichскрипт, найденный в Debian, для правильной реализации.
Стефан Шазелас

typeвстроенный в , ksh93u+ 2012-08-01кажется, работает правильно.
Стефан Шазелас

5

Флаг --all или -a покажет вам все совпадения на вашем пути и псевдонимы (по крайней мере, в Fedora, Ubuntu и CentOS):

which -a which

В AIX и Solaris это приблизит вас:

echo "$PATH" | sed -e 's/:/ /g' | \
while read -r p; do find "$p" -type f -name "which"; done

Вам нужны двойные кавычки вокруг замены параметров, иначе скрипт не будет работать, если он $PATHсодержит пробелы или символы-заглушки оболочки. read -rнеобходимо справиться с обратными слешами. Это не очень хороший метод, потому что findон займет много времени и может вернуть ложные совпадения, если каталог $PATHсодержит подкаталоги. К счастью, здесь findэто не полезно; смотри мой ответ.
Жиль "ТАК - перестань быть злым"

Я знал, что find чувствовал себя неправильно, так как он наверняка будет медленным во вложенных каталогах. Глобирование и пробелы в $ PATH? EWW. Но вы правы (хотя вы были достаточно хороши, чтобы не сказать так много): мой единственный вкладыш был написан плохо.
Эли Хедри

1

Если у вас нет whichподдержки -aили whenceнет, сверните свои собственные:

#!/bin/sh -f

IFS=":"
for PART in $PATH
do
  if test -x "$PART/$1"
  then
    echo $PART/$1
  fi
done

Тебе не хватает set -fвыключения болтовни на незащищенных $PATH. test -fнедостаточно, так как здесь требуются только исполняемые файлы; вам нужно test -x. Хм, я понимаю, что я забыл обычный тест файла в моем сценарии.
Жиль "ТАК ... перестать быть злым"

@ Жиль: отредактировано в соответствии с вашими советами. Я все за правильность, но нахожу whence README.txtтак же маловероятно, как whence "file* wi?h we!rd name". Просто пытаюсь показать, как легко пройти $PATH.
MattBianco

0

ksh и zsh имеют «откуда» как встроенную оболочку. whence -aделает то, что вы хотите под Zsh:

 7:27AM 7 % whence -a cat
/usr/bin/cat
/bin/cat
/usr/bin/cat
/bin/cat

Я должен очистить PATH в Zsh, у меня есть много дубликатов в нем. whence -aиначе работает под ksh:

$ whence -a cat
cat is a tracked alias for /usr/bin/cat

Должен сказать, что это тоже кажется потенциально полезным поведением.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.