【问题标题】:"getpwnam() failed" in /bin/sh only when called from cron仅当从 cron 调用时 /bin/sh 中的“getpwnam() failed”
【发布时间】:2017-06-11 05:29:51
【问题描述】:

这是我的 crontab 文件的内容:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO="example@example.com"

*/5 * * * * sh /robot/1/master.sh >/dev/null 2>&1
*/5 * * * * sh /robot/2/master.sh >/dev/null 2>&1
*/5 * * * * sh /robot/3/master.sh
*/5 * * * * sh /robot/4/master.sh >/dev/null 2>&1
*/5 * * * * sh /robot/5/master.sh >/dev/null 2>&1

这是/var/log/cron 尝试运行时一直显示的错误:

crond[669]: (sh) ERROR (getpwnam() failed)

如果我手动运行这些文件中的任何一个,它们都可以正常工作。

crontab 文件有什么问题?

【问题讨论】:

  • 旁白:sh 不是 bash(即使它是 bash 的符号链接,它也以兼容模式运行,转换了许多功能)。如果您实际上没有使用 bash,请不要标记您的问题。
  • 您是每半分钟还是每 5 分钟运行一次 cron? */5 表示它将每分钟运行一次,步长为 5。
  • 无论如何,getpwnam() failed 总的来说非常简单。您系统的目录服务/存储是什么?例如,如果它被配置为与需要 Kerberos 身份验证的事物通信,那么您的 cron 作业可能没有有效的票证。
  • ...也就是说:问题实际上与您的 crontab 文件无关,而与您的系统目录服务的方式有关——它提供了信息getpwnam()查询 -- 已配置。这将意味着在你的系统配置中挖掘一下。
  • @DanielCortés */5 表示它将每 5 分钟运行一次。

标签: shell cron sh crontab


【解决方案1】:

令我惊讶的是,没有人对此有正确的答案。今天我遇到了完全相同的问题,谷歌没有帮助。

2 小时后,我发现在 /etc/cron.d 中放置文件时,计划行必须包含一个额外的选项.....

我总是将它用于我的 crontab -e

# Minute   Hour Day of Month     Month          Day of Week     Command    
# (0-59)  (0-23)   (1-31)  (1-12 or Jan-Dec)  (0-6 or Sun-Sat)  /my/fancy/script.sh            

所以它包含 6 个项目。

当把它放在 /etc/cron.d 内的文件中时,cron 需要一个额外的选项,作为运行您的幻想/脚本的用户。

# Minute   Hour Day of Month     Month          Day of Week     Who   Command    
# (0-59)  (0-23)   (1-31)  (1-12 or Jan-Dec)  (0-6 or Sun-Sat)  root  /my/fancy/script.sh            

这在 man crontab(5) 中有记录。例如 https://linux.die.net/man/5/crontab 。它说:

/etc/cron.d/ 中的作业

cron.d 中的作业是系统作业,通常用于多个用户。这就是为什么需要用户名的原因。第一行的 MAILTO 是可选的。

【讨论】:

  • 嘿。好点——如果你有一个缺少字段的系统 crontab,我们会寻找一个名为 sh 的用户,这肯定会导致 getpwnam() 失败。
  • 甚至我的 VPS 的系统管理员都不知道是什么原因造成的,哈哈。顺便说一句,你为什么使用路径 /etc/cron.d/ 而不是 /etc/crontab
  • 我使用目录/etc/cron.d,因为我可以为每个任务创建一个具有描述性名称的文件。因为我喜欢这样....../etc/crontab 是一个我从未修改过的文件。
  • @Anthony:这也是添加包拥有的 crontab 条目的自然方式。 (这就是我今天遇到这个问题的方式。)这应该是公认的答案。
【解决方案2】:

第六个位置是为运行作业的用户名保留的。您指定了一个名为 sh 的用户,该用户很可能不在计算机上。

【讨论】:

    【解决方案3】:

    简单的答案 在您的 crontab 上,您需要指定 USER 来运行命令

    以 ROOT 身​​份运行的示例是:-

    0,10,20,30,40,50 * * * * root /path_to_script/script_name

    或以用户 FRED 身份运行

    0,10,20,30,40,50 * * * * fred /path_to_script/script_name

    未指定 USER 的默认设置是以 CRON 用户身份运行,并且该用户无权执行脚本

    【讨论】:

      【解决方案4】:

      crontab 文件没有任何问题(只要“我的”crontab 表示它是用户 crontab 而不是系统 crontab;否则,see other answer)。

      另一方面,您系统的目录服务有问题 - 在 Linux 中配置为 nsswitch.conf。也许您正在使用经过 Kerberos 身份验证的 LDAP 存储,而您的 cron 守护程序没有 Kerberos 令牌来连接它(或者是沙盒,与 SELinux 一样,没有网络访问权限);也许它是运行 crontab 的用户无法读取的文件存储;也许还有其他一些奇怪而有趣的事情正在发生。

      getpwnam() 是一个 C 库调用,用于查找当前登录用户的名称。如果你的 shell 是 bash,它会退回到 I have no name! 的名称——所以这个错误意味着你的 sh 实现是不同的。 (如果您想使用 bash 运行脚本,请使用 bash,而不是 sh)。

      【讨论】:

        【解决方案5】:

        我们可以为系统以及个人创建 cron 作业。 /etc/crontab 中的 crontab 专门用于系统 cronjobs。所以需要指定由谁执行的cronjob命令。在问题中未指定用户名。因此出现ERROR (getpwnam() failed)。您可以在 /var/spool/cron/username 中创建用户特定的 cronjobs

        注意:: Cron 作业非常有用,但在失败时是灾难性的!

        【讨论】:

          猜你喜欢
          • 2020-08-14
          • 2022-01-04
          • 2023-02-06
          • 2020-02-23
          • 1970-01-01
          • 1970-01-01
          • 2022-08-19
          • 2010-09-14
          • 2012-10-11
          相关资源
          最近更新 更多