sudo, which, そしてバッククォート
ある web ページで、僕の書いたものを引用されていたのだが、
$ sudo `which <command>`と僕が書いていたのを、
$ sudo `which <command> <引数>`と誤解されているようだったので、コメントを入れておいたのだった。
そもそも、何故、
$ sudo `which <command>`などということをしなければならないのか、というと、これはちょっと前に sudo の仕様が変更されたことに起因している。以前は、sudo を使って管理者権限でコマンドを使うとき、そのコマンドの実行において、sudo を実行したユーザの環境変数が反映されるようになっていた。だから、root に妙な PATH を指定することなしに管理者権限のコマンドを使うのに、sudo は結構重宝な道具だったのである。
しかし、これはセキュリティ的にはよろしくない状況である。しかも、何か操作ミスがあったときのリスクも大きくなる。だから、ちょっと前から sudo は仕様を変更して、sudo 専用の環境変数のセットが用意され、sudo でコマンドを実行するときにはその環境変数が反映されるようになっている。
このような状況になると、あまりメジャーでないディレクトリにあるバイナリを起動しようとするときに、そこに PATH が通っていないことが問題になる。当然フルパスを書けばいいのだが、それは面倒極まりない。こういう場合、UNIX の流儀では、小さなコマンドを組み合わせて解決することになるわけだが、そこで先の、
$ sudo `which <command>`が登場するわけである。
(b)sh 系のシェルでは、バッククォートで囲まれた中身はコマンドとして展開される。つまり "which <command>" の実行結果が文字列としてここに嵌め込まれるわけだ。ここで重要なのは、"which <command>" は、sudo を実行するユーザの権限で実行されることである。つまり、このユーザの環境変数で PATH が通っていれば、このような書き方をすることで、フルパスを sudo に渡すことができるのである。
ここまで分かれば、何故引数をバッククォートの中に入れてはいけないのか、が分かろうというものだろう。うーん……しかしなあ。僕は何も文献など読まずに、この記法を見ただけでそのココロが分かったのだが、そんなに難しいものなのだろうか? 説明が足らなかったのかなあ。