シェルスクリプトの自動運転でsudoのタイムアウトを設ける


シェルスクリプトの自動運転でsudoを使うには、NOPASSWDで、かつ !requiretty な設定をすればよいのだが、うっかりsudoできないユーザーでこれを実行してしまった場合、いつまでもパスワードの入力待ちで止まってしまう。これに気付かず後続処理が走ってしまうのは怖いのだが、 /etc/sudoers.d/ユーザー名 のファイルをgrepして判断しようにもsudoを使わないといけない(rootで実行すればよいとか言わないで><)。

そこでぽぽは考えましたよ。「(ぴこーん!) 最初にsudoで何かしらの無害なコマンドを叩かせて終了ステータスを捕まえればええんやぁ!」

というわけでこんな処理をスクリプトの最初に仕込んでやればよい。

sudoコマンドの前にtimeoutコマンドを挟む

sudoコマンドの前にtimeoutコマンドを挟んでおけば、sudoersにいないユーザーがこれを実行しようとすると必ずパスワード入力待ちになる。つまり、人間の入力待ちで必然的にタイムアウトする仕組みを利用している。sudoersにいるユーザーといないユーザーで手動実行結果を比較してみるとこうなる。

sudoersに設定のあるnullpopopoユーザーがechoコマンドを実行して正常終了している、つまり終了ステータスが0であるのに対し、sudoersに設定のないmarinaユーザーはtimeoutコマンドで異常終了している、つまり終了ステータスが0ではない、ということである。

ちなみにbashの内部コマンドで : があるじゃないか、という声がどこかから聞こえてきたのでついでを言うと、 : は正常終了を返すコマンドであるので、(前段のtimeoutコマンドで異常終了するとはいえ)成否判定に用いるのは不適切である。かつ、bashの内部コマンドであるためPATHが通っていないので、終了ステータスを捕まえる以前に使いにくい。

だったら、echoでも吐いておけという判断になる。シェルスクリプトの自動実行で少しでもハマりポイントが減らせればこれ幸い。ね、簡単でしょう?