Bash:如何在后台运行“sudo -n true”而不干扰“read”?

Bash:如何在后台运行“sudo -n true”而不干扰“read”?

我有一个长时间运行的 Bash 脚本,我不想以 root 身份运行它,但它需要定期进行 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"

除了 之外,我无法使用任何其他命令复制此行为sudo。如何sudo -n true在不干扰的情况下在后台运行read

编辑:

我只在 Ubuntu 上遇到这个问题,在 macOS 上没有。

答案1

我得到同样的行为:

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

sudo打开/dev/tty以查询当前前台进程组,这会导致read()bash 进行的系统调用read以 EAGAIN 返回,而 Ubuntu 18.04 的 Linux 内核 4.15.0-45-generic 和 4.18.0-14-generic 至少会导致read实用程序返回与该错误。

这似乎是由Linux 内核的 Ubuntu 变体最新版本中的一个错误。我无法在 Solaris 和 FreeBSD 上重现它,也无法在 Debian 上的任何版本的 Linux 上重现它(尽管如果我在 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小时前

4.18.0-15-generic 现已登陆 Ubuntu 存储库并修复了该问题。我想 4.15 的版本很快就会推出。

ksh93对于相同的代码没有问题,因为它的read内置函数首先使用select()等待输入,并且select()当其他进程打开时不返回/dev/tty

所以这里你可以使用ksh93代替bash或等待修复内核或返回到 4.15.0-43 直到 4.15.0-46 发布。

或者,您可以使用zsh它内置支持更改 uid(通过 EUID/UID/USERNAME 特殊变量),前提是您启动脚本,这样root您就不需要sudo在脚本内运行(延长脚本的寿命也有潜在的危险) sudo 令牌比用户预期的要长)。

相关内容