Intereting Posts
Существует ли команда UNIX / Linux для * UNMAP * перераспределенных (плохих) секторов жесткого диска? Почему команда ImageMagick `compare` настолько медленная и есть альтернатива? Как избежать <или> в параметре в оболочке? Не удается войти в систему после запуска автозапуска службы при запуске Невозможно добавить нового пользователя в группу sudo Как установить ядро ​​на debian без подключения к Интернету Как сделать PDF-портфолио из объединенных файлов Как отправить стандартный ввод через трубу Команда tput не работает в операторе if Периодически вызывается arp для проверки возможности подключения? Открытые программы без блокировки терминала через Putty Восстановить последний аргумент последней команды в режиме bash 'vi Проблема с беспроводным светодиодным индикатором netctl: несколько точек доступа Wi-Fi с одинаковым SSID Добавление значений во втором столбце, если первая запись столбца одинакова в UNIX

Как использовать (1) с системным значением $ PATH?

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

мотивация

Я пытаюсь написать сценарий, чтобы найти двоичный файл системы 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. Вот некоторые идеи, которые могут сработать:

  1. Отфильтруйте версии в домашнем каталоге пользователя (и относительные пути):

     ( 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 ) 
  2. Отфильтровать версии в каталоге 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 ) 
  3. Отфильтруйте записываемые рубины (в крайнем случае, предполагается, что они не работают как 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 ) 
  4. Спросите 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"