初めに
タイトルから分かる人もいると思いますが、sudoするためにはtty(端末)が必要なので、もちろんプログラミング言語の外部コマンドAPIから呼び出すときもrequirettyをコメントアウトする必要があるというものです。
サンプルがpythonですが、どの言語でも同様だと思います。
sudoの例として「service docker restart」ですが、sudoのものであれば、serviceコマンドやdockerでなくても、なんでもいいと思いますが、自己責任でお願いします。
個人的な動機
自動的にdockerの環境構築しては破棄するようなスクリプトを組んでるのですが、しばらく動かすと「too many open files」とかエラーを吐いて止まるので、dockerのサービス自体を再起動する対処療法をしてます。
しかし、一般ユーザー権限で実行されたスクリプトでは、serviceコマンドが呼べません。
その時の調べた方法の備忘録です。
目標
import commands
commands.getstatusoutput("sudo service docker restart")
これを、一般ユーザー権限で実行した時に正常に実行するのが目標です。
作業
もちろん、システムに何も設定しないと動きません。
エラーを拾って表示しないと、わかりませんが
「sudo を実行するには tty がなければいけません。すみません」
とご丁寧に謝ってくれてます。
(まず僕は、ここで少しハマリました)
% visudo
から
Defaults requiretty
の行(56行目くらいにある)をコメントアウトしてください。
これで sudoを実行するのに tty(端末)が必要無くなります。
しかし、これでもパスワードを要求されるので、しかもプログラム的に渡すのが多分面倒なので、
「service docker restart」だけは、パスワードなしで実行したいと思います。
(注意: 以下の方法は、このスクリプトに限らず、このユーザー自体に「service docker restart」はパスワードなしに実行できてしまうことに注意してください。将来これ以外の方法を追記するかもしれません。)
再び
% visudo
コマンドで以下の一行を追加します。
(sudoできるということは前半部分は記述されてると思いますので、変更かもしれません)
(ユーザー名) ALL=(ALL) PASSWD: ALL, NOPASSWD:/sbin/service docker restart
簡単にいうと、基本的にsudoするときは、通常通りパスワードを必要とするが、
/sbin/service docker restart
の実行はパスワードが要らないということです。
(端末からは service だけで良いからといって/sbin/を忘れがちなのに注意、僕はハマリました)
これで晴れて、目標のpythonから外部コマンドAPIからsudoのコマンドが呼べるようになりました。
(多分もっといい方法があると思います。)
参考
sudo を実行するには tty がなければいけません。すみません と謝るFedoraをなだめる
http://qiita.com/hash/items/7c8018c30c670fdd71fb