LoginSignup
6
9

More than 5 years have passed since last update.

プログラミング言語の外部コマンドAPIからsudoのコマンドを呼ぶ方法(requiretty)

Posted at

初めに

タイトルから分かる人もいると思いますが、sudoするためにはtty(端末)が必要なので、もちろんプログラミング言語の外部コマンドAPIから呼び出すときもrequirettyをコメントアウトする必要があるというものです。

サンプルがpythonですが、どの言語でも同様だと思います。
sudoの例として「service docker restart」ですが、sudoのものであれば、serviceコマンドやdockerでなくても、なんでもいいと思いますが、自己責任でお願いします。

個人的な動機

自動的にdockerの環境構築しては破棄するようなスクリプトを組んでるのですが、しばらく動かすと「too many open files」とかエラーを吐いて止まるので、dockerのサービス自体を再起動する対処療法をしてます。
しかし、一般ユーザー権限で実行されたスクリプトでは、serviceコマンドが呼べません。

その時の調べた方法の備忘録です。

目標

sudoを伴うpythonからのコマンド呼び出し
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

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9