Почему не работал bash-скрипт или про возврат каретки

от автора

Я писал свой конфигурационный файл для Conky. Захотел сделать вывод доллара и евро по отношению к рублю и посчитать динамику курсов. Задача не сложная, поэтому я быстро написал bash-скрипт. Курсы валют решил взять с сайта ЦБРФ.

Скрипт получился такой:

#!/bin/bash now=`date +%d/%m/%Y` onedayago=`date --date="1 day ago" +%d/%m/%Y` twodayago=`date --date="2 day ago" +%d/%m/%Y` wget -O now.tmp -q "http://www.cbr.ru/scripts/XML_daily.asp?date_req=$now" wget -O onedayago.tmp -q "http://www.cbr.ru/scripts/XML_daily.asp?date_req=$onedayago" wget -O twodayago.tmp -q  "http://www.cbr.ru/scripts/XML_daily.asp?date_req=$twodayago" nowk=`cat now.tmp | grep "USD"  -A3  | sed -n -e 4p | tr -d "A-Za-z<>/\t'" | sed -e s/\,/\./` onedayagok=`cat onedayago.tmp | grep "USD"  -A3  | sed -n -e 4p | tr -d "A-Za-z<>/\t" | sed -e s/\,/\./` twodayagok=`cat twodayago.tmp | grep "USD"  -A3  |sed -n -e 4p | tr -d "A-Za-z<>/\t" `  dinamika=`echo $onedayagok-$nowk | bc` echo $dinamika

Однако при запуске скрипта я получал сообщение об ошибке:

(standard_in) 1: illegal character: ^M
(standard_in) 1: illegal character: ^M

В чём же дело? Решил посмотреть переменные отдельно. Добавил две строки:

 echo $nowk echo $onedayagok 

Вывод переменных был корректным:

Может быть, ошибка в строке

echo $onedayagok-$nowk

? Добавим вывод этой строки командой

echo $onedayagok-$nowk

Вывелось только -58.7710. Куда же делось 59.4452? Вот тут и возникли трудности. Решил я сделать запись вывод результата операции в файл, добавили >1.txt и >2.txt после обработки данных, то есть получилось так:

 nowk=`cat now.tmp | grep "USD"  -A3  | sed -n -e 4p | tr -d "A-Za-z<>/\t" | sed -e s/\,/\./ >1.txt` onedayagok=`cat onedayago.tmp | grep "USD"  -A3  | sed -n -e 4p | tr -d "A-Za-z<>/\t" | sed -e s/\,/\./ >2.txt` 

С виду всё было нормально, цифры успешно записались в файл.

Стал изучать довольно странную и неожиданную проблему дальше. Решил сам создать файл с таким же содержанием. С помощью текстового редактора nano создаём файл 3.txt и вписываем в него 59.4452. В файл 4.txt вписываем 58.7710. В скрипт добавляем чтение из файла, то есть:

 nowk=`cat 3.txt` onedayagok=`cat 4.txt` 

Всё работало. Cтало очевидно, что проблема в полученных данных. Надо было просто проанализировать файлы 2.txt и 3.txt. Далее открываем оба файла hex-редактором и находим ту самую разницу:

Файлы почти идентичны, однако в файле 2.txt присутствует 0D. С помощью поисковой системы находим, что OD — «перевод каретки». То есть при команде echo $onedayagok-$nowk сначала выводилось значение переменной onedayagok, далее же с начала строки в этой же строке выводилась переменная nowk, то есть перекрывая прежнюю переменную. С помощью той же поисковой системы узнаём, что для удаления «картеки» добавляем ‘\r’ в утилиту tr, то есть так:

 nowk=`cat now.tmp | grep "USD"  -A3  | sed -n -e 4p | tr -d "A-Za-z<>/\t'\r'" | sed -e s/\,/\./` onedayagok=`cat onedayago.tmp | grep "USD"  -A3  | sed -n -e 4p | tr -d "A-Za-z<>/\t'\r" | sed -e s/\,/\./` twodayagok=`cat twodayago.tmp | grep "USD"  -A3  |sed -n -e 4p | tr -d "A-Za-z<>/\t'\r'" ``  

Убеждаемся, что скрипт теперь работает. ЦБР возвращает данный с «переводом каретки». В этом и была проблема. К сожалению, о таких нюансах не рассказывают в учебниках и статьях по bash, поэтому могут возникнуть такие трудности.

ссылка на оригинал статьи http://habrahabr.ru/post/254123/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *