【问题标题】:bash error "date: invalid date `24/06/2013 21:22'" with Debian but not with RHEL?bash 错误“日期:无效日期‘24/06/2013 21:22’”与 Debian 但不是 RHEL?
【发布时间】:2013-06-24 16:38:06
【问题描述】:

我正在使用一个脚本,它根据在任何给定的 Kerberos 票证中找到的内容创建两个变量。被称为 $TCACHE 的 kerberos 票证看起来像这样......:

Ticket cache: FILE:/tmp/krb5cc_12345_gbiRMw
Default principal: testuser@TEST.SITE

Valid starting    Expires           Service principal
24/06/2013 11:22  24/06/2013 21:22  krbtgt/TEST.SITE@TEST.SITE
        renew until 01/07/2013 11:22

...以及有问题的变量像这样...:

EXPIRE_TIME=$( date -d "$( klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}' )" +%s )
RENEW_TIME=$( date -d "$( klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}' )" +%s )

这两个都在 RHEL 5 和 6 下正常工作...:

EXPIRE_TIME

# date -d "$( klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}' )" +%s             
1372122061
#  date -d "$( klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}' )"
Mon Jun 24 21:01:01 EDT 2013
# klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}'             
06/24/13 21:01:01

RENEW_TIME

# date -d "$( klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}' )" +%s 
1372046400
# klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}'
07/01/13 08:24:15
# klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}'
07/01/13 08:24:15

然而,在 Debian 7 下,我得到了这个...:

EXPIRE_TIME

# date -d "$( klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}' )" +%s
date: invalid date `24/06/2013 21:22'
# date -d "$( klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}' )"
date: invalid date `24/06/2013 21:22'
# klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}'            
24/06/2013 21:22

RENEW_TIME

# date -d "$( klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}' )" +%s
1357575720
# date -d "$( klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}' )"      
Mon Jan  7 11:22:00 EST 2013
# klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}'            
01/07/2013 11:22

作为参考,这里只是 date 命令在每台服务器上的输出...:

RHEL 6

# date
Mon Jun 24 12:29:06 EDT 2013

DEBIAN 7

# date
Mon Jun 24 12:29:18 EDT 2013

谁能解释并帮助我了解如何缓解这种情况?

谢谢。

更新 1:我发现这个错误报告完美地描述了这个问题:http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=697954

...所以我想我毕竟不会发疯。

更新 2:我从实验版安装了 krb5-user 1.11,正如宣传的那样,问题消失了。

【问题讨论】:

  • 嗯,我看到的一个区别是 Debian 上的 klist 给出了一个四字节的年份(2013),而 RedHat 上的 klist 给出了一个两字节的年份(13)。这是你所期望的吗?
  • 另外,我想知道美国和欧洲的日期表示是否存在差异。 07/01/13 在美国和欧洲都有效,而24/06/2013 只能是欧洲。因此,如果您的 date 命令需要美式格式,那肯定是个问题。
  • @chrisaycock - 我实际上没有注意到这一点。不过,不确定它会有所作为。我的困惑是为什么在 Debian 上,两个看似相同的命令(一个查看 krbtgt,另一个“更新直到”)不会产生相同的输出。我还想知道这是否也是日期格式问题;就像你说的关于欧洲和美国的日期。我不确定如何判断 Debian 在这方面使用的是什么。现在我想多了,我怀疑这可能是最有可能的情况。
  • @chrisaycock - 花了我一秒钟,但我记得 RHEL6 和 Debian7 服务器的语言环境命令和“LC_TIME”都设置为“LC_TIME="en_US.UTF-8"”。
  • 所以你的date 命令想要一个美国约会,而你给了它一个欧洲约会。听起来我们找到了问题所在。

标签: bash debian kerberos klist


【解决方案1】:

这个问题与date命令在不同平台如何解析日期有关。

  • 在 Debian 中,它被解析为 MM/DD/YYYY。
  • 在 RHEL 中,它被解析为 DD/MM/YYYY。

这是设计使然。如果您想知道,请在源代码中进行硬编码。在parse-datetime.y源码中,可以阅读以下内容:

如果第一个值有 4 位或更多位,则解释为 YYYY/MM/DD, 否则为 MM/DD/YY。识别 YYYY/MM/DD 的目的仅仅是为了 支持旧机器生成的日期,例如 RCS 日志中的日期 清单。如果您需要可移植性,请使用 ISO 8601 格式。

通常,解析字符串应始终被视为不安全:无法保证此类代码始终有效。因此,您可以做的最好的事情是在将您读取的日期发送到日期命令之前将其调整为 ISO 8601。这可以通过正则表达式来完成。

这是你的便携代码:

EXPIRE_TIME=$( date -d "$( klist -c $TCACHE | grep -m1 krbtgt | awk '{print $3, $4}' | sed -r 's#([0-9]+)/([0-9]+)/([0-9]+)#\3-\2-\1#g' )" +%s )
RENEW_TIME=$( date -d "$( klist -c $TCACHE | grep -m1 "renew until" | awk '{print $3, $4}' | sed -r 's#([0-9]+)/([0-9]+)/([0-9]+)#\3-\2-\1#g' )" +%s )

如果您有兴趣通过代码检查date 预期的格式,您可以使用已知的冲突日期进行测试:

# Try to parse a known conflicting date
date -d "30/01/2010" >/dev/null 2>/dev/null

# Test Exit Code
if [ $? ]; then
  # Returned error, so the expected format is MM/DD/YYYY
else
  # No error, so the expected format is DD/MM/YYYY
fi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-19
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多