Я хотел бы использовать это, используя путь по умолчанию к системе, игнорируя любые приукрашивания из файлов конфигурации оболочки пользователя.
Я пытаюсь написать сценарий, чтобы найти двоичный файл системы Ruby. Многие разработчики Ruby используют менеджер версий Ruby, который добавляет что-то вроде ~/.rvm/bin
к началу их $PATH
. Я хочу обойти это и использовать версию Ruby, которая поставляется вместе с системой, или была установлена через диспетчер пакетов системы.
Вот что я пробовал до сих пор:
$ env -i sh -c "which ruby"
Это не дает выхода и выходит с 1. Я бы ожидал, что он будет работать, потому что путь включает /usr/bin
, а моя система поставляется с двоичным /usr/bin/ruby
Ruby в /usr/bin/ruby
:
$ env -i sh -c "echo \$PATH" /usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:. $ which -a ruby # ... /usr/bin/ruby
Несколько дополнительных деталей:
env -s bash -c "which ruby"
тоже ничего не находит. env -i zsh -c "which ruby"
находит /usr/bin/ruby
, но я не могу зависеть от zsh
. which
(чтобы убедиться, что я использую двоичный файл, а не встроенную оболочку), не имеет никакого значения. Я пишу это в Bash на OS X, но хотел бы, чтобы он был переносимым для других оболочек и операционных систем.
command -pv
использует «значение по умолчанию для PATH».
$ which ruby /home/mikel/.rvm/rubies/ruby-1.9.3-p484/bin/ruby $ command -pv ruby /usr/bin/ruby
К сожалению, это не работает в zsh
, поэтому на основе комментария Stephane мы можем использовать getconf PATH
:
$ PATH=$(getconf PATH) which ruby
или используйте command -v
вместо which
, как рекомендовано в Почему не использовать «что»? Что использовать тогда?
$ PATH=$(getconf PATH) command -v ruby
Недостатком этих подходов является то, что если системный администратор установил общесистемную версию в say /usr/local/bin
или /opt/local/bin
, и все пользователи имели это в PATH
(например, через /etc/profile
или /etc/environment
или подобное), вышеуказанное, вероятно, не нашло бы его.
В вашем конкретном случае я предлагаю попробовать что-то конкретное для Ruby. Вот некоторые идеи, которые могут сработать:
Отфильтруйте версии в домашнем каталоге пользователя (и относительные пути):
( IFS=: set -f for dir in $PATH; do case $dir/ in "$HOME/"*) ;; /*/) if [ -f "$dir/ruby" ] && [ -x "$dir/ruby" ]; then printf '%s\n' "$dir/ruby" break fi;; esac done )
Отфильтровать версии в каталоге rvm
( IFS=: set -f for dir in $PATH; do case $dir/ in "$rvmpath/"*) ;; /*/) if [ -f "$dir/ruby" ] && [ -x "$dir/ruby" ]; then printf '%s\n' "$dir/ruby" break fi;; esac done )
Отфильтруйте записываемые рубины (в крайнем случае, предполагается, что они не работают как root)
( IFS=: set -f for dir in $PATH; do case $dir/ in /*/) ruby=$dir/ruby if [ -f "$ruby" ] && [ -x "$ruby" ] && [ ! -w "$ruby" ]; then printf '%s\n' "$ruby" break fi;; esac done )
Спросите rvm
, chruby
и т. Д.
( rvm system chruby system command -v ruby )
Последний способ делает rvm
выбирать по умолчанию Ruby, но мы делаем это в подоболочке, чтобы впоследствии пользовательский Ruby был восстановлен. ( chruby
part untested.)
Явная установка значения $PATH
в под-оболочке решает проблему:
env -i sh -c "PATH=\$PATH which ruby"
Обратите внимание, что $
in $PATH
экранировано, что означает, что $PATH
в команде sub-shell не заменяется значением родительской оболочки $PATH
до выполнения команды (это также может быть достигнуто с использованием одинарных кавычек).
Мне было бы очень интересно узнать, почему это необходимо в этом случае.
Обычно вы не хотите использовать which
команду. В Bash вы должны использовать команды type
или команды. См. Это вопросы и ответы по причинам, почему: « Почему бы не использовать« что »? Что использовать тогда? ,
$ type -a ls ls is aliased to `ls --color=auto' ls is /bin/ls
или это:
$ type -a vim vim is /usr/bin/vim
или это:
$ command -v ls alias ls='ls --color=auto'
или это:
$ command -v vim /usr/bin/vim
Из справочной страницы Баша.
выдержка по типу
type [-aftpP] name [name ...] With no options, indicate how each name would be interpreted if used as a command name. If the -t option is used, type prints a string which is one of alias, keyword, function, builtin, or file if name is an alias, shell reserved word, function, builtin, or disk file, respectively. If the name is not found, then nothing is printed, and an exit status of false is returned. If the -p option is used, type either returns the name of the disk file that would be executed if name were specified as a command name, or nothing if ``type -t name'' would not return file. The -P option forces a PATH search for each name, even if ``type -t name'' would not return file. If a command is hashed, -p and -P print the hashed value, not necessarily the file that appears first in PATH. If the -a option is used, type prints all of the places that contain an executable named name. This includes aliases and functions, if and only if the -p option is not also used. The table of hashed commands is not consulted when using -a. The -f option suppresses shell function lookup, as with the command builtin. type returns true if all of the arguments are found, false if any are not found.
выдержка из команды
command [-pVv] command [arg ...] Run command with args suppressing the normal shell function lookup. Only builtin commands or commands found in the PATH are executed. If the -p option is given, the search for command is performed using a default value for PATH that is guaranteed to find all of the standard utilities. If either the -V or -v option is supplied, a description of command is printed. The -v option causes a single word indicating the command or file name used to invoke command to be displayed; the -V option produces a more verbose description. If the -V or -v option is supplied, the exit status is 0 if command was found, and 1 if not. If neither option is supplied and an error occurred or command cannot be found, the exit status is 127. Otherwise, the exit status of the command builtin is the exit status of command.
Выделите параметр PATH просто «/ usr / bin» (или установите PATH в качестве) в качестве параметра для env. env -i игнорирует окружающую среду, которую он наследует, следующая настройка PATH позволит найти / usr / bin / ruby.
env -i PATH="/usr/bin" sh -c "which ruby"