%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%3F.png)
which
ユーザーシェル設定ファイルの変更を無視し、システムのデフォルトパスを使用したいと思います。
やる気
私のシステムのRubyバイナリを見つけるためのスクリプトを書こうとしています。多くのRuby開発者はRubyバージョンマネージャを使用し、それ自身~/.rvm/bin
の$PATH
。
現在のソリューション
これが私が今まで試したことです:
$ env -i sh -c "which ruby"
これは出力を提供せずに1で終了します。パスには次のものが含まれており/usr/bin
、私のシステムに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
(シェル組み込みではなくバイナリを使用していることを確認するために)、違いはありません。
私の環境
私はOS XのBashでこの記事を書いていますが、他のシェルやオペレーティングシステムに移植できることを願っています。
答え1
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
使用してください。「which」を使わないのはなぜですか?それでは何を使うべきですか?
$ PATH=$(getconf PATH) command -v ruby
この方法の欠点は、システム管理者が/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 )
書き込み可能なルビーフィルタリング(最後の手段、ルートとして実行されないと仮定)
( 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
部分的にテストされていません。)
答え2
$PATH
サブシェルで明示的に値を設定すると、問題が解決します。
env -i sh -c "PATH=\$PATH which ruby"
$
inはエスケープされます。これは$PATH
、コマンドを実行する前にサブシェル$PATH
コマンドが親シェルの値に置き換えられないことを意味します(単一引用符を使用して実行することもできます)。$PATH
この場合、これがなぜ必要なのか知りたいです。
答え3
通常、このコマンドを使用したくありませんwhich
。 Bashではtype
orコマンドを使用する必要がありますcommand
。理由については、次のQ&Aをご覧ください。「which」を使わないのはなぜですか?それでは何を使うべきですか?。
はい
$ 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
Bashのマニュアルページから。
タイプ抜粋
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.
答え4
envの引数としてPATH設定を「/usr/bin」に指定するか、適切なPATHを設定するだけです。 env -iは継承された環境を無視します。次のPATH設定を使用すると、/usr/bin/rubyを見つけることができます。
env -i PATH="/usr/bin" sh -c "which ruby"