対象読者: Ruby・Pythonなどの初心者で、こんなエラーメッセージが出てきて困っている人
$ fluentd
rbenv: fluentd: command not found
The `fluentd' command exists in these Ruby versions:
2.6.3
rbenv や pyenv などの、**env
を使っていると、このようなエラーメッセージが出てくることがあります。
この問題を解決するには**env
の仕組みを理解する必要があります。
**env
の仕組み
そもそも、**env
を使っていると、このようにディレクトリを移動しただけで、ruby
やpython
のバージョンが自動で切り替わるようになりますが、これはどのように実現されているのでしょう?
$ ruby --version
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
$ cd my-project
$ cat .ruby-version
2.4.5
$ ruby --version
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]
実はここで実行している ruby
は、本物のruby
ではありません!~/.rbenv/shims/
に置かれたスクリプトなのです。
$ which ruby
/Users/x-xxxxx/.rbenv/shims/ruby
$ cat ~/.rbenv/shims/ruby
#!/usr/bin/env bash
set -e
[ -n "$RBENV_DEBUG" ] && set -x
program="${0##*/}"
if [ "$program" = "ruby" ]; then
for arg; do
case "$arg" in
-e* | -- ) break ;;
*/* )
if [ -f "$arg" ]; then
export RBENV_DIR="${arg%/*}"
break
fi
;;
esac
done
fi
export RBENV_ROOT="/Users/x-xxxxx/.rbenv"
exec "/Users/x-xxxxx/.rbenv/libexec/rbenv" exec "$program" "$@"
bundler
, gem
などの同梱コマンドや、Gemによって追加されるコマンドも同様です。
$ which gem
/Users/x-xxxxx/.rbenv/shims/gem
$ which bundle
/Users/x-xxxxx/.rbenv/shims/bundle
$ which fluentd
/Users/x-xxxxx/.rbenv/shims/fluentd
そして、普通にrbenv init
でセットアップすると、$PATHの先頭に~/.rbenv/shims/
が追加されて最優先で使用されます。
エラーメッセージが表示されるまでの流れ
~/.rbenv/shims/
のスクリプトは現在使用中のバージョンのRuby内の同名のコマンドを実行しようとします。
そのため、現在使用中のバージョンのRubyにコマンドがインストールされていなければ、エラーになります;
- あなたが
fluentd
を実行する -
$PATH
が先頭から検索され、最初に見つかる~/.rbenv/shims/fluentd
実行される -
~/.rbenv/shims/fluentd
は現在のディレクトリから .rbenv-version を検索し、Rubyのバージョンを決定する - そのバージョンのRuby内の
flunetd
を実行しようとするがfluentd
が見つからない(別バージョンのRubyにはインストールされているが) - 下記のエラーメッセージを表示
$ fluentd
rbenv: fluentd: command not found
The `fluentd' command exists in these Ruby versions:
2.6.3
対策
コマンドを絶対パスで指定する
~/.rbenv/shims/hoge
を経由せずに直接実行します。
~/.rbenv/versions/2.6.1/bin/ruby
$PATHの先頭に追加する
~/.rbenv/shims より先にパスを追加します。
なお、RubyやPythonにはコマンドを、(インタープリターのディレクトリではなく)ホーム直下のディレクトリにインストールする機能があります。そのディレクトリを$PATHに追加すると良いでしょう。
$ export PYTHONUSERBASE=~/.local
$ pip3 install --user awscli
$ ls ~/.local/bin jupyter-notebook
$ ls ~/.local/bin/
jupyter
jupyter-bundlerextension
jupyter-console
jupyter-kernel
...
# ~/.bashrc
eval "$(pyenv init -)"
export PATH=$HOME/.local/bin:$PATH
rbenv init を使わない
実は rbenv init
を使わなくても、rbenv install
でRubyをビルドすることはできます。
人によってはビルドできるだけで十分かもしれません。
pipenv や bundler 経由で使う
RubyやPythonのコマンドをグローバルにインストールして使うというのが、そもそもトラブルの元です。常に pipenv や bundler 経由で使いましょう。