Я писал свой конфигурационный файл для 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, поэтому могут возникнуть такие трудности.
Автор: vodopad