为什么 cron 在我的脚本中默默地无法运行 sudo 内容?

为什么 cron 在我的脚本中默默地无法运行 sudo 内容?

我有一个从非特权用户的 crontab 运行的脚本,它使用sudo.但事实并非如此。该脚本运行良好,但 sudo 命令会默默失败。

  • 该脚本以相关用户的身份从 shell 完美运行。

  • Sudo 不需要密码。相关用户已(root) NOPASSWD: ALL在 中授予访问权限/etc/sudoers

  • Cron 正在运行并执行脚本。添加一个简单的date > /tmp/log会在正确的时间产生输出。

  • 这不是权限问题。同样,脚本确实被执行,只是没有执行 sudo 命令。

  • 不是路径问题。env从正在运行的脚本内部运行会显示$PATH包含 sudo 路径的正确变量。使用完整路径运行它没有帮助。正在执行的命令被赋予完整路径名。

  • 尝试捕获 sudo 命令的输出(包括 STDERR)不会显示任何有用的信息。添加sudo echo test 2>&1 > /tmp/log到脚本会产生空白日志。

  • sudo 二进制文件本身执行良好,并且即使从脚本内的 cron 运行时也能识别它具有权限。添加sudo -l > /tmp/log到脚本会产生输出:

    用户 ec2-user 可以在此主机上运行以下命令:
    (root) NOPASSWD: ALL

使用检查命令的退出代码$?显示它返回错误(退出代码:)1,但似乎没有产生错误。命令就像/usr/bin/sudo /bin/echo test返回相同的错误代码一样简单。

还有什么可能发生的事情?

这是最近创建的虚拟机,运行最新的 Amazon Linux AMI。 crontab 属于用户ec2-user,sudoers 文件是发行版默认文件。

答案1

sudo其权限文件中有一些特殊选项,其中之一允许限制其对在 a 内运行的 shell 的使用TTY,但事实cron并非如此。

包括 Amazon Linux AMI 在内的一些发行版默认启用此功能。该/etc/sudoers文件将如下所示:

# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
#         You have to run "ssh -t hostname sudo <cmd>".
#
Defaults    requiretty

#
# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
#
Defaults   !visiblepw

STDERR如果您在 shell 脚本级别而不是 sudo 命令本身捕获了输出,那么您将会看到类似这样的消息:

抱歉,您必须有 tty 才能运行 sudo

TTY解决方案是通过删除或注释掉这些选项来允许 sudo 在非环境中执行:

#Defaults    requiretty
#Defaults   !visiblepw

答案2

有点晚了,OP可能不再感兴趣,但对于其他可能sudo在 a 中使用的人来说user crontab,这是一个潜在的解决方案:

sudo不要在 a 中使用,而是user crontab使用root crontab

$ sudo crontab -e

一些系统 - 取决于sudo配置方式 -sudouser crontab实际中使用(例如 Raspberry Pi OS)。然而,使用root crontab是一种更便携的方法;它还消除了使用sudo来运行任何命令或脚本的需要。因此,如果您sudo mount 'blah, blah'在 a 中使用user crontab,它就会mount 'blah, blah'root crontab.

如果您不知道在 下运行的作业的环境是什么cron,您可以通过将此条目添加到( )cron来要求告诉您:root crontabsudo crontab -e

0 12 * * * /usr/bin/printenv > /home/user_me/cronenvironment_sudo.txt 2>&1

更改user_me为您系统上的实际用户名,然后查看crontab大师寻求日程安排方面的帮助。

最后,请参阅此问答以了解如何改变环境在cron

相关内容