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

в 14:45, , рубрики: bash, 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

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

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


echo $nowk
echo $onedayagok

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

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

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

echo $onedayagok-$nowk

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

echo $onedayagok-$nowk

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

Вывелось только -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`

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

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

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


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

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

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

Файлы почти идентичны, однако в файле 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-скрипт или про возврат каретки - 6

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

Автор: vodopad

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js