bash error "date: invalid date `24/06/2013 21:22'" with Debian but not with RHEL?

820 Views Asked by At

I am using a script that creates two variables based on what it finds in any given Kerberos ticket. The kerberos ticket, referenced as $TCACHE, would look like this ... :

Ticket cache: FILE:/tmp/krb5cc_12345_gbiRMw
Default principal: [email protected]

Valid starting    Expires           Service principal
24/06/2013 11:22  24/06/2013 21:22  krbtgt/[email protected]
        renew until 01/07/2013 11:22

... and the variables in question like this ... :

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 )

Both of these work normally under RHEL 5 and 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

Under Debian 7, however, I get this instead ... :

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

For reference, here's the output of just the date command on each server ... :

RHEL 6:

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

DEBIAN 7:

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

Can anyone explain and help me understand how to mitigate this?

Thanks.

UPDATE 1: I found this bug report that describes the issue perfectly: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=697954

... so I guess I'm not going crazy after all.

UPDATE 2: I installed krb5-user 1.11 from experimental and, as advertised, the problem went away.

1

There are 1 best solutions below

0
On

This problem is related to how date command parse the date in different platforms.

  • In Debian it is parsing as MM/DD/YYYY.
  • In RHEL it is parsing as DD/MM/YYYY.

This is done by design. Hardcoded in the source code if you want to know. In parse-datetime.y source, you can read the following:

Interpret as YYYY/MM/DD if the first value has 4 or more digits, otherwise as MM/DD/YY. The goal in recognizing YYYY/MM/DD is solely to support legacy machine-generated dates like those in an RCS log listing. If you want portability, use the ISO 8601 format.

In general, parsing strings should always be treated as unsafe: there is no guarantee that this type of code will always work. So the best you can do is to adapt the date you read to ISO 8601 before send it to date command. This can be done with Regex.

So here is your portable code:

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 )

If you are interested to check, via code, the format expected by date you can test with a known conflicting 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