Существует отчет об ошибках по этой проблеме в системе отслеживания ошибок Debian, упоминая, что нестабильные репозитории Debian уже зафиксировали пакеты (и базы данных пакета показывает, что они уже поражают Debian/testing repos). Так как Crunchbang 10 "Statler" основан на Debian/stable, эти фиксированные пакеты могли занять время, чтобы быть доступными там; Вы можете однако смешивание и подгонка, если Вы немного осторожны (см., например, этот вопрос).
executable=mysql
executable_path=$(command -v -- "$executable") &&
dirname -- "$executable_path"
Конечно, это не будет работать если $executable
встроенная оболочка, функция или псевдоним. Я не знаю ни о какой оболочке где mysql
встроенное. Это не будет функцией или исказит, если Вы не определили их ранее, но затем необходимо знать об этом. Исключение к этому могло быть bash
который поддерживает экспортируемые функции.
$ bash -c 'command -v mysql'
/usr/bin/mysql
$ mysql='() { echo test;}' bash -c 'command -v mysql'
mysql
В целом этой команды нужно избежать.
Почему?
Поскольку это использует Вашу текущую среду при построении $PATH
то, что это собирается оценить при поиске исполняемых файлов. Это может привести к беспорядку при контакте со сценариями оболочки и таким, который будет потенциально использовать $PATH
как создано Вашим ~/.bashrc
и ~/.bash_profile
файлы при выполнении.
Например:
# path to start
$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/sam/bin
# let's change it
$ export PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin
$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin
# simulate a new env. for a shell script
$ bash -lc "echo \$PATH"
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/sam/bin
Заметьте, что сценарий оболочки, если выполняется имел бы исходную среду, не текущую!
Можно также использовать команду type
определять местоположение исполняемых файлов в Вашей среде:
$ type ls
ls is aliased to `ls --color=auto'
Или видеть все, используйте -a
переключатель:
$ type -a ls
ls is aliased to `ls --color=auto'
ls is /bin/ls
type
покажет, что Вы искажаете, а также местоположение. Для нахождения каталога, хотя, @StephaneChazelas решение использования command
является лучшим.
Можно также использовать команду whereis
но это не использует Вашу среду, она имеет hardcoded набор каталогов, что она заглядывает. Посмотрите человека whereis для получения дополнительной информации.
Этот мог бы смутить людей, но некоторые дистрибутивы включают инструмент, который работает от задания крона, обычно ежедневно, который сканирует весь диск и создает немного файла базы данных, который можно затем искать использование locate
команда.
/etc/cron.daily/mlocate.cron
в моей системе Fedora 14. /usr/bin/updatedb
./var/lib/mlocate/mlocate.db
. Используя то, что я рассмотрел бы определенным взломом, который можно подключить коаксиальным кабелем locate
только искать файлы, которые называют ls
следующим образом:
$ locate -b '\ls'
/bin/ls
/usr/share/javadoc/java-1.6.0-openjdk/api/org/w3c/dom/ls
/usr/share/javadoc/java-1.6.0-openjdk/jre/api/plugin/dom/org/w3c/dom/ls
/usr/share/locale/l10n/ls
/var/cache/abrt-di/usr/src/debug/gcc-4.5.1-20100924/libjava/classpath/external/w3c_dom/org/w3c/dom/ls
/var/cache/abrt-di/usr/src/debug/gcc-4.5.1-20100924/libjava/classpath/gnu/xml/dom/ls
Вышеупомянутые работы, потому что Вы \
globbing символ, таким образом, это отключает неявную замену ls
с *ls*
.
См. определять местоположение страницу справочника для получения дополнительной информации.
Менее известный инструмент называют whatis
. Этот подобен locate
, таким образом, это поддерживается DB. Это полезно для обнаружения команд однако:
$ whatis ls
ls (1) - list directory contents
ls (1p) - list directory contents
Инструмент вызывается от задания крона, /etc/cron.daily/makewhatis.cron
. Однако makewhatis
создает его базу данных из man
страницы в Вашей системе.
Вы видите больше об этом в makewhatis страницах справочника.
Можно использовать команду dirpath
против любого вывода, произведенного командами, я упомянул выше для получения просто компонента каталога.
dirpath
не делает никакой проверки, таким образом, можно дать ему примерно любой тип пути к файлу, и это даст Вам часть каталога:
$ dirname /some/path/to/a/script
/some/path/to/a
dirname является самым простым способом достигнуть этого:
$ which mysql
/usr/bin/mysql
$ dirname `which mysql`
/usr/bin
Как другие объяснили, не использовать which
.
Можно записать немного функции оболочки, которая выполняет итерации по PATH
переменная.
which-directory () (
IFS=:
set -g
for d in $PATH; do
if [ -z "$d" ]; then d=.; fi
if [ -x "$d/$1" ]; then printf '%s\n' "$d"; return; fi
done
return 1
)
С другой стороны, можно звонить command -v
. Это сообщает о псевдонимах и функциях, а также внешних командах. В случае, если у Вас есть псевдоним или функция mysql
это называет внешнюю команду того же имени с дополнительными параметрами, можно звонить command -v
в недавно запущенной оболочке, которая не имеет никаких функций или искажает определенный. Обратите внимание, что это делает правильную вещь только если псевдоним или вызовы функции внешняя команда того же имени. Следующие две остроты эквивалентны (предположение, что у Вас нет каталога или имени исполняемого файла на Вашем ПУТИ, содержащем новую строку).
dirname -- "$(sh -c 'command -v "$0"' -- mysql)"
sh -c 'command -v "$0"' -- mysql | sed -e 's!.*/!!'
В zsh эта острота делает то же самое:
echo =mysql(:h)
which
. – a CVn 01.08.2013, 18:04which
плохо в моем ответе.Сообщите мне, что Вы об этом думаете. – slm♦ 01.08.2013, 18:47.
. (Поскольку существует псевдоним, которыйwhich
не знает.) Zsh имеет очень удобное=mysql
синтаксис, но к сожалению это не складывает с${…##*/}
или…:h
. – Gilles 'SO- stop being evil' 02.08.2013, 02:59${${:-mysql}:c:h}
все же. ksh и zsh имеютwhence -p
к обратным каналам команд, даже если существует встроенное/искажать/функциональное для него, но затем это не могло бы быть тем, что Вы хотите, поскольку это не то, что вызвала бы оболочка. – Stéphane Chazelas 02.08.2013, 09:59