2013-06-24 8 views
3

Я использую скрипт, который создает две переменные, основанные на том, что он находит в любом данном билете Kerberos. Керберос билет, ссылаются как $ TCACHE, будет выглядеть следующим образом ...:ошибка bash "дата: неверная дата` 24/06/2013 21:22 '"с Debian, но не с RHEL?

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 

... и переменные в вопросе, как это ...:

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 

Для справки, вот выход только команды даты на каждом сервере ...:

RHEL 6:

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

DEBIAN 7:

# date 
Mon Jun 24 12:29:18 EDT 2013 
Может

кто объяснить и помочь мне понять, как смягчить это?

Спасибо.

UPDATE 1: Я нашел это сообщение об ошибке, описывающее проблему прекрасно: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=697954

... так что я думаю, я не схожу с ума после того, как все.

ОБНОВЛЕНИЕ 2: Я установил krb5-user 1.11 из экспериментального и, как было объявлено, проблема исчезла.

+1

Хм, единственное различие, которое я вижу, это то, что 'klist' на Debian дает четырехбайтовый год (2013), в то время как' klist' на RedHat дает двухбайтовый год (13). Это то, чего вы ожидаете? – chrisaycock

+2

Кроме того, я задаюсь вопросом, есть ли разница в представлении даты в США и Европе. '07/01/13' действует как в Америке, так и в Европе, а' 24/06/2013' может быть только европейским. Поэтому, если ваша команда 'date' ожидает американский формат, это определенно будет проблемой. – chrisaycock

+0

@chrisaycock - Я на самом деле этого не заметил. Не уверен, что это изменит ситуацию. Моя путаница заключается в том, почему на Debian две, казалось бы, идентичные команды (один смотрит на krbtgt, а другой «обновляется до») не производит одинаковый вывод. Я также задался вопросом, является ли это также вопросом формата даты; как вы говорите о датах в Европе и США. Я не знаю, как сказать, что Debian использует в этом отношении. Теперь, когда я думаю об этом больше, я подозреваю, что это, вероятно, самый вероятный случай. – user2516975

ответ

1

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

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

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

Интерпретировать ГГГГ/ММ/ДД, если первое значение имеет 4 или более цифр, иначе как MM/DD/YY. Целью распознавания 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