対象読者: 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 経由で使いましょう。