Bash:「読み取り」を中断せずにバックグラウンドで「sudo -n true」を実行する方法は?

Bash:「読み取り」を中断せずにバックグラウンドで「sudo -n true」を実行する方法は?

rootとして実行したくない長期実行Bashスクリプトがありますが、定期的にrootアクセスが必要です。ユーザーに root パスワードを要求してこの問題を解決しました。

sudo -v

次に、バックグラウンドで、次を使用してsudoタイマーを繰り返してリセットするプロセスを実行します。

sudo -n true

readその後、基本プロセスで使用すると奇妙な問題が発生し始めました。以下は、この問題を示す最小限のスクリプトです。実行して実行する前に何も入力しない場合は、sudo -n true読み取りからread error: 0: Resource temporarily unavailable

#!/usr/bin/env bash

sudo -v  # ask user for password

sleep 1 && sudo -n true &  # background a process to reset sudo

printf "Reading text: "
read -n 1 TEXT
echo "Read text: $TEXT"

このコマンドを除く他のコマンドを使用してこの動作を複製することはできませんsudosudo -n true邪魔することなくバックグラウンドでどのように実行できますかread

編集する:

この問題は、macOSではなくUbuntuでのみ発生します。

答え1

私も同じ行動をとります。

sleep 1 && true < /dev/tty &
read var

sudobashによるシステムコールがEAGAINに返されるよう/dev/ttyにする現在のフォアグラウンドプロセスグループを照会するために開きます。 Ubuntu 18.04 の Linux カーネル 4.15.0-45-generic および 4.18.0-14-generic は、少なくともユーティリティが次に返されるようにします。そのエラー。read()readread

これが原因のようです。LinuxカーネルのUbuntuバリアント最新バージョンのバグ。私はそれをSolarisとFreeBSDで再現することはできず、どのLinuxバージョンのDebianでも再現することはできません(Ubuntu 4.18カーネルでDebianを起動すると再現できますが)。

https://bugs.launchpad.net/ubuntu/+source/linux-signed-hwe/+bug/1815021エラーのもう一つの兆候のようです。

これは次のために発生します。https://lkml.org/lkml/2018/11/1/663Ubuntuは少なくとも4.15および4.18カーネルでバックポートされました。しかし、Ubuntuはバックポートされません。別の変更修理するこのパッチによって引き起こされる回帰~まで2時間前

これで、Ubuntuリポジトリで4.18.0-15-genericを使用できるようになり、この問題は解決されました。すぐに4.15バージョンが出ると思います。

ksh93read組み込み関数は最初にselect()入力待ちを使用し、select()他のプロセスが開いているときは返さないため、同じコードに問題はありません/dev/tty

したがって、ここksh93で代わりに使用するか、bashカーネルが変更されるのを待つか、4.15.0-46がリリースされるまで4.15.0-43に戻ることができます。

zshあるいは、スクリプトを起動すると(EUID / UID / USERNAME特殊変数を介して)uid変更の組み込みサポートを使用できるため、スクリプト内で実行するroot必要はありませんsudo(スクリプトの寿命を延ばす)。ユーザーが予想するよりも長いsudoトークンを使用すると、潜在的に危険になる可能性があります)。

関連情報