Ошибка bash "дата: неверная дата" 24.06.2013 21:22 "с Debian, но не с RHEL?

Я использую скрипт, который создает две переменные в зависимости от того, что он находит в любом билете Kerberos. Билет Kerberos, обозначенный как $TCACHE, будет выглядеть так:

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 на каждом сервере...:

РЕЛ 6:

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

ДЕБИАН 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 из экспериментальной версии, и, как было объявлено, проблема исчезла.

1 ответ

Эта проблема связана с тем, как date Команда разбора даты на разных платформах.

  • В Debian он анализируется как MM / DD / YYYY.
  • В RHEL он разбирается как DD / MM / YYYY.

Это сделано по замыслу. Закодировано в исходном коде, если вы хотите знать. В источнике parse-datetime.y вы можете прочитать следующее:

Интерпретировать как ГГГГ / ММ / ДД, если первое значение имеет 4 или более цифр, в противном случае как ММ / ДД / ГГ. Целью распознавания YYYY / MM / DD является исключительно поддержка устаревших машинно-сгенерированных дат, таких как даты в списке журналов RCS. Если вы хотите мобильности, используйте формат ISO 8601.

В целом, синтаксический анализ всегда должен рассматриваться как небезопасный: нет гарантии, что этот тип кода будет работать всегда. Поэтому лучшее, что вы можете сделать, - это адаптировать дату, которую вы прочитали, к ISO 8601 перед отправкой команды на дату. Это можно сделать с помощью Regex.

Итак, вот ваш портативный код:

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
Другие вопросы по тегам