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

Cal*_*leb 31 cron sudo

我有一个从非特权用户的 crontab 运行的脚本,该脚本使用sudo. 除了它没有。脚本运行良好,但 sudo 的命令默默地失败。

  • 该脚本作为相关用户从 shell 完美运行。

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

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

  • 这不是权限问题。再次执行脚本,而不是执行 sudo 的命令。

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

  • 尝试捕获包括 STDERR 在内的 sudo 命令的输出没有显示任何有用的信息。添加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 文件是发行版默认的。

Cal*_*leb 42

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
Run Code Online (Sandbox Code Playgroud)

如果您已将输出捕获到STDERRshell 脚本级别而不是 sudo 命令本身,那么您似乎会看到如下消息:

抱歉,你必须有一个 tty 才能运行 sudo

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

#Defaults    requiretty
#Defaults   !visiblepw
Run Code Online (Sandbox Code Playgroud)