キャッシュを削除してgemを復旧する
じつは前回、環境構築中に事故があった。
事故
Ruby ではてな OAuth のアクセストークンを取得する - blog.kymmt.com
はてなブログ API 用の gem を書いた - blog.kymmt.com
上記を参考にして、はてなブログAPI用gemをインストールする直前までやった。
$ gem install hatenablog
しかし、ここで事故発生。installing 20%
のような表示がでていたような気がするが、そこでフリーズしてしまった。
PCがメモリ不足により停止した。じつはLinuxMintにしてからよく起こる。仕方ないので再起動して再度コマンドを打つとエラーが出るようになった。
ERROR: While executing gem ... (NoMethodError) undefined method `spec' for nil:NilClass
hatenablogをインストールできない。
gemが壊れたか、設定ファイルがおかしくなったのかもしれない。 そこで、gemの親元と思われるRubyの再インストールから始めた。
復旧まで
Ruby削除
$ sudo apt-get --purge remove ruby パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下のパッケージが自動でインストールされましたが、もう必要とされていません: libyaml-0-2 これを削除するには 'apt-get autoremove' を利用してください。 以下のパッケージは「削除」されます: libruby1.9.1* ruby* ruby1.9.1* アップグレード: 0 個、新規インストール: 0 個、削除: 3 個、保留: 399 個。 この操作後に 13.2 MB のディスク容量が解放されます。 続行しますか? [Y/n] y (データベースを読み込んでいます ... 現在 185088 個のファイルとディレクトリがインストールされています。) libruby1.9.1 (1.9.3.484-2ubuntu1.2) を削除しています ... libruby1.9.1 (1.9.3.484-2ubuntu1.2) の設定ファイルを削除しています ... ruby1.9.1 (1.9.3.484-2ubuntu1.2) を削除しています ... ruby1.9.1 (1.9.3.484-2ubuntu1.2) の設定ファイルを削除しています ... ruby (1:1.9.3.4) を削除しています ... libc-bin (2.19-0ubuntu6.6) のトリガを処理しています ... man-db (2.6.7.1-1ubuntu1) のトリガを処理しています ... mint@mint-CF-T5AW1AXS ~ $ gem プログラム 'gem' は以下のパッケージで見つかりました: * ruby * rubygems 次の操作を試してください: sudo apt-get install <選択したパッケージ>
Ruby再インストール
$ sudo apt-get install ruby パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下の特別パッケージがインストールされます: libruby1.9.1 ruby1.9.1 提案パッケージ: ri ruby-dev ruby1.9.1-examples ri1.9.1 graphviz ruby1.9.1-dev ruby-switch 以下のパッケージが新たにインストールされます: libruby1.9.1 ruby ruby1.9.1 アップグレード: 0 個、新規インストール: 3 個、削除: 0 個、保留: 399 個。 2,720 kB 中 0 B のアーカイブを取得する必要があります。 この操作後に追加で 13.2 MB のディスク容量が消費されます。 続行しますか? [Y/n] y 以前に未選択のパッケージ ruby を選択しています。 (データベースを読み込んでいます ... 現在 184189 個のファイルとディレクトリがインストールされています。) .../ruby_1%3a1.9.3.4_all.deb を展開する準備をしています ... ruby (1:1.9.3.4) を展開しています... 以前に未選択のパッケージ ruby1.9.1 を選択しています。 .../ruby1.9.1_1.9.3.484-2ubuntu1.2_i386.deb を展開する準備をしています ... ruby1.9.1 (1.9.3.484-2ubuntu1.2) を展開しています... 以前に未選択のパッケージ libruby1.9.1 を選択しています。 .../libruby1.9.1_1.9.3.484-2ubuntu1.2_i386.deb を展開する準備をしています ... libruby1.9.1 (1.9.3.484-2ubuntu1.2) を展開しています... man-db (2.6.7.1-1ubuntu1) のトリガを処理しています ... ruby (1:1.9.3.4) を設定しています ... ruby1.9.1 (1.9.3.484-2ubuntu1.2) を設定しています ... libruby1.9.1 (1.9.3.484-2ubuntu1.2) を設定しています ... libc-bin (2.19-0ubuntu6.6) のトリガを処理しています ... mint@mint-CF-T5AW1AXS ~ $ sudo gem install oauth Successfully installed oauth-0.5.1 1 gem installed Installing ri documentation for oauth-0.5.1... Installing RDoc documentation for oauth-0.5.1...
oauthインストール
$ sudo gem install oauth
hatenablogインストール
$ sudo gem install hatenablog ERROR: While executing gem ... (NoMethodError) undefined method `spec' for nil:NilClass
spec
メソッドが未定義らしい。
調べた
"ERROR: While executing gem ... (NoMethodError) undefined method `spec' for nil:NilClass"で検索してみた。
ruby on rails - Error installing gems - Stack Overflow
翻訳してみると、gemのキャッシュが壊れたのが原因らしい。キャッシュが残らないようにアンインストールするコマンドを叩いたつもりだったのだが、gemは対象外だったのか?
- キャッシュに残っていてインストールされていないライブラリを見つける
- 1の
.gem
ファイルをキャッシュのディレクトリから削除する /usr/lib/ruby/gems/1.8/specifications/
にある空のgemspecファイルも削除する
キャッシュ・ディレクトリを調べる
$ gem env RubyGems Environment: - RUBYGEMS VERSION: 1.8.23 - RUBY VERSION: 1.9.3 (2013-11-22 patchlevel 484) [i686-linux] - INSTALLATION DIRECTORY: /var/lib/gems/1.9.1 - RUBY EXECUTABLE: /usr/bin/ruby1.9.1 - EXECUTABLE DIRECTORY: /usr/local/bin - RUBYGEMS PLATFORMS: - ruby - x86-linux - GEM PATHS: - /var/lib/gems/1.9.1 - /home/mint/.gem/ruby/1.9.1 - GEM CONFIGURATION: - :update_sources => true - :verbose => true - :benchmark => false - :backtrace => false - :bulk_threshold => 1000 - REMOTE SOURCES: - http://rubygems.org/
上記で得られたパスは以下の4つ。子ディレクトリにキャッシュらしきディレクトリがあった。
パス | cacheディレクトリ |
---|---|
/var/lib/gems/1.9.1 |
○ |
/usr/bin/ruby1.9.1 |
✘ |
/usr/local/bin |
✘ |
/home/mint/.gem/ruby/1.9.1 |
○ |
/usr/bin/ruby1.9.1
はそもそもruby1.9.1
ディレクトリがなかった。
キャッシュ・ディレクトリ内のライブラリを調べる
/var/lib/gems/1.9.1/cache
- oauth-0.5.1.gem
- nokogiri-1.6.8.1.gem
- mini_portile2-2.1.0.gem
/home/mint/.gem/ruby/1.9.1
- oauth-0.5.1.gem
インストール済みライブラリ一覧
$ gem list *** LOCAL GEMS *** mini_portile2 (2.1.0) oauth (0.5.1)
nokogiri-1.6.8.1.gem
がない。つまり、nokogiri-1.6.8.1.gem
のインストールが完了していない。そのキャッシュを削除すればいい。
削除する
nokogiri-1.6.8.1.gem
/var/lib/gems/1.9.1/cache
- nokogiri-1.6.8.1.gem
ファイルサイズをみると0バイトだった。
ファイラでは削除できなかったので、以下のコマンドで削除した。
$ sudo rm nokogiri-1.6.8.1.gem
gemspec
/usr/lib/ruby/gems/1.8/specifications/
にある空のgemspecファイルも削除するらしいが、みつけられなかった。/usr/lib/ruby/1.9.1
ならあったが、配下にgem
ディレクトリすらなかった。/home/mint/.gem/ruby/1.9.1
配下にspecifications
らしきものはなかった。
/var/lib/gems/1.9.1/specifications
ならあった。しかし、ここにnokogiri-1.6.8.1.gemspec
はなかった。以下の2つのみ。
- oauth-0.5.1.gemspec
- mini_portile2-2.1.0.gemspec
存在しないなら、もう大丈夫かな?再インストールしてみる。
復旧した
$ gem install hatenablog Fetching: nokogiri-1.6.8.1.gem (100%) ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions into the /var/lib/gems/1.9.1 directory.
パーミッションエラー。いつもsudoを付け忘れる。
$ sudo gem install hatenablog [sudo] password for mint: Fetching: nokogiri-1.6.8.1.gem (100%) Building native extensions. This could take a while... ERROR: Error installing hatenablog: ERROR: Failed to build gem native extension. /usr/bin/ruby1.9.1 extconf.rb /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError) from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require' from extconf.rb:4:in `<main>' Gem files will remain installed in /var/lib/gems/1.9.1/gems/nokogiri-1.6.8.1 for inspection. Results logged to /var/lib/gems/1.9.1/gems/nokogiri-1.6.8.1/ext/nokogiri/gem_make.out
問題となっていた以下のエラーは解消した。
ERROR: While executing gem ... (NoMethodError) undefined method `spec' for nil:NilClass
これにてgemの復旧が完了した。
新たなエラー
しかし、新たなエラーによりhatenablogがインストールできていない。
このエラーは次に考えるとして、今回のことをまとめてみる。
原因の分析
おそらく、フリーズしてインストール途中だったのがnokogiri-1.6.8.1.gem
なのだろう。
hatenablog
でnokogiri
を利用していたが、私の環境にはnokogiri
が存在しなかった。なのでまずはnokogiri
からインストールした。しかし、フリーズ事故により今回の件になったと。こういう場合は今回のようにgemのキャッシュを削除すれば復旧できると。
所感
余計な仕事が増える……。楽をするためのツールなのに、それらに振り回されているという現実。まさに本末転倒。
しかし、手段を一旦目的として学習せねば超えられない大きな壁に挑んでいるのだ。私は前進した。と、自分をなぐさめる。それすら進むために必要な手続き。