Сценарий оболочки, сравнивающий даты

#bash #shell #unix #cygwin

#bash #оболочка #unix #cygwin

Вопрос:

Я работаю над сценарием оболочки, который удаляет дату с веб-страницы, а затем проверяет, соответствует ли она последним трем дням текущей даты (запускаю ее в Cygwin). Если тест пройден, он просто повторяет «PASS», а если он завершается неудачей, он повторяет «FAIL»;

Однако, когда я запускаю свой скрипт, я получаю следующее:

 integer expression expected: 1317618000
FAIL
  

Вот сценарий:

 updateStr=$(curl "http://www.mywebsite.com" | grep "Last Update")
dateStr=(`echo $updateStr | sed -e 's/.*Last Update: ([^<]*)<.*/1/'`)
update=$(date -d "$dateStr"  %s)
epoch=$(date -d "-3 days ago"  %s)
test "$update" -ge "$epoch" amp;amp; echo "PASS" || echo "FAIL"
  

Есть идеи, в чем проблема?

Редактировать

Вот результат выполнения bash -x скрипта:

 $ bash -x check_date.sh
   curl http://www.mywebsite.com
   grep 'Last Update'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                             Dload  Upload   Total   Spent    Left  Speed
100  6542  100  6542    0     0    789      0  0:00:08  0:00:08 --:--:--  1544
  updateStr='                <span style="float:right">Last Update: 10/3/2011 2:
'8:45 AM</span></p>
   echo '<span' 'style="float:right">Last' Update: 10/3/2011 2:58:45 'AM</span><
'p>
   sed -e 's/.*Last Update: ([^<]*)<.*/1/'
' dateStr='(10/3/2011 2:58:45 AM)
'  %ste -d '(10/3/2011 2:58:45 AM)
  update=$'1317618000r'
   date -d '-3 days ago'  %s
  epoch=$'1317938194r'
  test $'1317618000r' -ge $'1317938194r'
: integer expression expected1317618000
  echo FAIL
FAIL
  

Обновить

Я попытался удалить возвраты каретки, которые отображаются в выходных данных даты, но это все еще не работает. Вот обновленный сценарий:

 updateStr=$(curl "http://mywebsite.com" | grep "Last Update")
dateStr=$(echo $updateStr | sed -e 's/.*Last Update: ([^<]*)<.*/1/')
update=$(date -d "$dateStr"  %s | tr -d 'r')
epoch=$(date -d "3 days ago"  %s | tr -d 'r')
echo "Last Update: $update"
echo "Epoch Date:  $epoch"
test "$update" -ge "$epoch" amp;amp; echo "PASS" || echo "FAIL"
  

И вот результат:

 $ bash -x ./check_date.sh
   curl http://mywebsite.com
   grep 'Last Update'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6542  100  6542    0     0  17398      0 --:--:-- --:--:-- --:--:-- 19704
  updateStr='                <span style="float:right">Last Update: 10/6/2011 2:
'0:02 AM</span></p>
   echo '<span' 'style="float:right">Last' Update: 10/6/2011 2:40:02 'AM</span><
'p>
   sed -e 's/.*Last Update: ([^<]*)<.*/1/'
' dateStr='10/6/2011 2:40:02 AM
'  %ste -d '10/6/2011 2:40:02 AM
   tr -d 'r'
  update=$'1317886802r'
   date -d '-3 days ago'  %s
   tr -d 'r'
  epoch=$'1318184767r'
' echo 'Last Update: 1317886802
Last Update: 1317886802
' echo 'Epoch Date:  1318184767
Epoch Date:  1318184767
  test $'1317886802r' -ge $'1318184767r'
: integer expression expected: 1317886802
  echo FAIL
FAIL
  

Комментарии:

1. Можете ли вы показать, что в echo $dateStr

2. можете ли вы добавить -x в свой #!/bin/bash, чтобы он выводился при выполнении каждой команды?

3. Я собираюсь догадаться, не пробуя себя, что тесту не нравятся эти возвраты каретки. В противном случае я не понимаю, почему это приведет к сбою.

4. @frankc: Да, наверное, это так. Я удивлен, что не заметил их раньше.

5. -3 days ago это 3 дня в будущем — это действительно то, с чем вы пытаетесь сравнить?

Ответ №1:

Возврат каретки может быть в самом вашем скрипте. Попробуйте запустить dos2unix свой скрипт.

Комментарии:

1. Как я могу запустить dos2unix в моем скрипте? Я использую этот скрипт fmwconcepts.com/imagemagick/textcleaner и получаю эту ошибку.

2. Я запускаю команду в терминале cygwin с именем файла dos2unix, но все равно показываю ожидаемое сообщение с целочисленным выражением

Ответ №2:

Попробуйте это:

 update=$(date -d "$dateStr"  %s | tr -d 'r')
epoch=$(date -d "-3 days ago"  %s | tr -d 'r')
  

Это избавит от возврата каретки в конце каждого числа, что может помочь.

Комментарии:

1. Хм … по какой-то причине это, похоже, не удаляет возврат каретки из чисел, поэтому я все еще получаю ту же ошибку.

2. Это Gnu tr ? Похоже, это работает в моей системе. Я думаю, проверьте свою справочную страницу. Вы также можете попробовать ввести C-v C-m, чтобы ввести фактический символ возврата каретки в вашу командную строку, но это было бы сомнительно внутри скрипта.

3. Я предполагаю, что это связано с использованием Cygwin.

Ответ №3:

bash определяет из контекста (наличие ‘ r’ в данном случае), что это строки, а не целые числа. Двоичный оператор ‘-ge’ ожидает целочисленные аргументы и поэтому выдает ошибку. Предложение Тома Зича будет работать, а также использовать операторы сравнения строк, такие как ‘<‘ или ‘>’, которые могут дать неожиданные результаты, если строка по какой-либо причине плохо отформатирована. Я не уверен, есть ли способ принудительно выводить дату как целое число или нет…

Ссылки:

http://tldp.org/LDP/abs/html/untyped.html

http://tldp.org/LDP/abs/html/comparison-ops.html

Комментарии:

1. Знаете ли вы, почему решением Тома не было бы удаления символов ‘ r’? Кажется, я не могу обойти эту проблему…