要点
⑴sudoした場合は環境変数を引き継がない。
⑵sudoで環境変数を引き継ぐにはsudo -E some_commandかsudoersにenv_keepを書く。
⑶sudo ${pathが通っているコマンド}を実行する場合、カレントユーザのpathによって実行するコマンドが決まる。
sudoについて調べたきっかけ
今まで**「root権限でコマンドを実行したい場合」**にsudoを使っていたのですが、
とあるrubyのスクリプトをsudoで実行したところ以下のようなエラーがでました。
$ sudo /usr/local/hoge/fuga.rb
/usr/local/hoge/fuga.rb:3:in `require': no such file to load -- thor (LoadError)
from /usr/local/hoge/fuga.rb:3
rootとカレントユーザで見てるgemが違うのか?と思い、以下のようにgemのインストール済みのlistを見てみたところ、やっぱり入っていた。であれば、sudoでコマンド実行時にエラーが出てくるのはおかしいので、おそらくsudoについて誤認識をしていると感じ、改めてsudoについて調べてみました。
$ sudo gem list | grep thor
thor (0.19.1)
sudoとは
ITproの記事によれば以下の通りでした。
sudoは,指定したユーザーでコマンドを実行する。デフォルトではroot権限で実行する。suの代わりに使われることが多い。sudoを実行するには,あらかじめ/etc/sudoersファイルに権限を与えられるユーザーとコマンドを設定しておく必要がある。
ref: http://itpro.nikkeibp.co.jp/article/COLUMN/20071205/288862/
sudoを実行するには,あらかじめ/etc/sudoersファイルに権限を与えられるユーザーとコマンドを設定しておく
ということだったので、現在の/etc/sudoersの確認をvisudoで行い、自分のユーザないしグループがsudoers登録されていることを確認しました。
そして、調べていくうちにsudoは/etc/sudoersのデフォルト設定では環境変数を引き継がないということを思い出し、もしsudoで環境設定を引き継ぎたい場合は設定ファイルにための設定をenv_keep
で行う(※1)か、もしくはsudo -E some_command
によってコマンド実行すれば良い(※2)ということがわかりました。
ref※1: http://qiita.com/akito1986/items/e9ca48cfcd56fdbf4c9d
ref※2: http://mikio.github.io/article/2012/03/10_sudo.html
エラー原因の解決へ
sudoについて調べてわかった事のうち解決の手がかりになりそうな事は、自分の環境でsudoしてもpathは引き継がないということでした。
そこで、sudoした場合にどのgem使っているのか調べたところ、以下のようになりました。
# カレントユーザの場合
$ which gem
/usr/local/rbenv/shims/gem
$ which ruby
/usr/local/rbenv/shims/ruby
# sudoした場合
$ sudo which gem
which: no gem in (/usr/bin:/bin:/usr/sbin:/sbin)
$ sudo which ruby
/usr/bin/ruby
つまり、sudo gem list | grep thor
で出ていたthorは、カレントユーザの環境変数であるpathの通っているgem(/usr/local/rbenv/shims/gem)をsudoで実行し結果表示したに過ぎ無いということです。sudoした場合、そもそも別のrubyを使用していることがわかり、gemにもpathは通っていませんでした。
なお、当然ですが環境変数を引き継ぐための最も簡単な方法として-Eをつけて実行したところうまく行きました。
sudo -E /usr/local/hoge/fuga.rb