我有一个从非特权用户的 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
配置方式 -sudo
在user crontab
实际中使用(例如 Raspberry Pi OS)。然而,使用root crontab
是一种更便携的方法;它还消除了使用sudo
来运行任何命令或脚本的需要。因此,如果您sudo mount 'blah, blah'
在 a 中使用user crontab
,它就会mount 'blah, blah'
在root crontab
.
如果您不知道在 下运行的作业的环境是什么cron
,您可以通过将此条目添加到( )cron
来要求告诉您:root crontab
sudo crontab -e
0 12 * * * /usr/bin/printenv > /home/user_me/cronenvironment_sudo.txt 2>&1
更改user_me
为您系统上的实际用户名,然后查看crontab大师寻求日程安排方面的帮助。
最后,请参阅此问答以了解如何改变环境在cron
。