Измените базу элементов массива с восьмеричной на десятичную (внутри локального скрипта bash, который запускается удаленно)

У меня проблема в скрипте bash снизу.

Я ЗАПУСКАЮ КОД, ТАК КАК ОНО РАЗМЕЩЕНО ЗДЕСЬ

Код моего bash-скрипта:

#! /bin/bash
CMD='
# go to a specific path
set -x
cd share/Images
# create an array, perform the extraction of dates from folders names , populate the array with dates
declare -a all_dates
j=0
s=0
all_dates=($(ls | grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}"))
len=${all_dates[@]}
# vrification if dates are extracted correct
echo "$len"
# compare the dates
if [[ '$1' == '$2' ]]; then
echo "first important date and second important date are equal"
else
echo "first important date and second important date are different"
fi
# show the index of each elemnts and highlight the index of 2 important dates that are provided as arguments from comandline
for i in ${all_dates[@]}; do
echo "$i"
echo " Index is $j for array elemnt ${all_dates[$i]}"
# comparison with first important date
if [[ '$1' == ${all_dates[$j]} ]]; then
echo " bingo found first important date: index is $j for element ${all_dates[$j]}"
fi
# comparison with second important date
if [[ '$2' == ${all_dates[$j]} ]]; then
echo " bingo found second important date: index is $s for element ${all_dates[$j]}"
fi
j=$(($j+1))
s=$(($s+1))
done
'
ssh -t user@server << EOT
$CMD
EOT

Это вывод кода сверху:

Index is 16 for array elemnt 
+ echo 2016-04-05
+ echo ' Index is 16 for array elemnt '
+ [[ 2016-03-15 == 2016-04-05 ]]
+ [[ 2016-03-26 == 2016-04-05 ]]
+ j=17
+ s=17
+ for i in '${all_dates[@]}'
2016-04-08
+ echo 2016-04-08
-sh: line 22: 2016-04-08: value too great for base (error token is "08")

Также структура элементов моего массива ГГГГ-ММ-дд. Ошибка появляется в операторе for, поэтому необходимо изменить базу (с восьмеричной на десятичную). У меня было несколько попыток, я думаю, что это наиболее близко к решению, но мне это не удалось:

for i in "${all_dates[@]}"; do all_b+=( $((10#$i)) ) 
echo "${all_b[@]}"
done

Любая помощь приветствуется!


person Mihai    schedule 28.11.2019    source источник
comment
Просто используйте bc вместо этого.   -  person stephanmg    schedule 28.11.2019
comment
@stephanmg Я пытался, но результат тот же. Может быть, я использовал его неправильно. Как вы предлагаете его использовать?   -  person Mihai    schedule 28.11.2019
comment
echo "obase=10; ibase=8; OCTAL NUMBER HERE" | bc преобразует восьмеричное число в десятичное.   -  person stephanmg    schedule 28.11.2019
comment
Боюсь, я не могу воспроизвести ошибку ни с одной версией bash под рукой. Строка 2016-04-08 должна быть безвредной, пока она обрабатывается как строка. Это может вызвать ошибку при использовании в арифметическом контексте, включая индекс массива, но я не могу найти такое использование в вашем опубликованном коде. Действительно ли опубликованный код вызывает указанную ошибку, или вы не упростили свой код, чтобы задать вопрос? БР.   -  person tshiono    schedule 29.11.2019
comment
@tshiono Привет. На данный момент это мой код, я планирую реализовать другие функции, но поскольку эта часть кода вызывает проблемы, я должен ее решить. Я запускаю скрипт локально на VirtualMachine с Ubuntu 16.04 и работаю удаленно на сервере QTS. Я тестировал локально, и все работало отлично, проблема возникает, когда я использую удаленный доступ. Структура имен папок такая: 'Asrgv_Image_G_2016_04_08_20_24_33' ad я извлекаю только дату и работаю с ней.   -  person Mihai    schedule 29.11.2019
comment
Хм... Есть несколько причин, по которым я сомневаюсь, что опубликованный код и ваш код не идентичны. 1) В опубликованном коде есть нечетная shebang строка в начале. 2) Я протестировал код на удаленном сервере qnap, который работает хорошо. 3) Вы упоминаете, что имя папки что-то вроде Asrgv_Image_G_2016_04_08_20_24_33, и вы extracting только дата, но опубликованный код просто проверяет соответствие строки без extracting. 4) В опубликованном коде предполагается, что строка даты разделена тире -, а имя папки в вашем комментарии разделено символом подчеркивания _, как указано выше. я вообще в недоумении..   -  person tshiono    schedule 29.11.2019
comment
@tshiono . О, теперь я сравниваю, и я пропустил кое-что, что я добавлю в начальный пост. Извините, я сделал ошибку, структура такая Asrgv_Image_G_2016-04-08-20-24-33 . Извлечение 2016-04-08 происходит в этой строке all_dates=($(ls | grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}")), и это сделает мой массив all_dates, а элементы массива будут такими: `2016-03-15 2016-03-18' и так далее.   -  person Mihai    schedule 29.11.2019
comment
@tshiono Хорошо, я обновил. Я пропустил j=0 and s=0 также часть после комментария # compare the dates и shebang от !# до #! Спасибо, вы гений :D Теперь пост такой же, как на моей виртуальной машине.   -  person Mihai    schedule 29.11.2019
comment
Спасибо за обновление. Понял насчёт extraction. Но ваш обновленный скрипт по-прежнему работает без проблем. Что, если вы скопируете и вставите опубликованный код и попытаетесь его выполнить? Я полагаю, что самого кода и имен папок на сервере достаточно, чтобы воспроизвести ошибку, верно (исключая встроенные команды Linux на сервере, конечно)?   -  person tshiono    schedule 29.11.2019
comment
Кстати, если я изменю строку if [[ '$1' == ${all_dates[$j]} ]]; then на if [[ '$1' -eq ${all_dates[$j]} ]]; then, это вызовет указанную ошибку: value too great for base.   -  person tshiono    schedule 29.11.2019
comment
Насколько я знаю, вывод, сгенерированный ==, не должен отличаться от -eq .   -  person Mihai    schedule 29.11.2019
comment
ОК, я попробовал скопировать код по вашему совету, но получил ту же ошибку. Одно ВАЖНОЕ упоминание в 3-й строке после утверждения for вместо ${all_dates[@]} должно быть ${all_dates[$i]}. Я обновлю сейчас. Я только что увидел, что если есть `${all_dates[@]}', ошибка не возникнет.   -  person Mihai    schedule 29.11.2019
comment
Рассмотрите возможность запуска удаленного сценария с параметром -x и совместного использования вывода (вставьте строку «set -x» перед начальным «cd»). Кроме того, где $1, $2?   -  person dash-o    schedule 29.11.2019
comment
@tshiono Спасибо за помощь, ты молодец! Хорошего дня!   -  person Mihai    schedule 02.12.2019


Ответы (2)


Как правило, всегда заключайте в кавычки любую переменную, которая входит в условие '[[' или '[', если вы не можете гарантировать, что значение не имеет какого-либо специального значения. В данном случае это относится ко всему, что ссылается на $1, $2 или если all_dates[$j]

# Old
if [[ '$1' == '$2' ]]; then
# New
if [[ "'$1'" == "'$2'" ]]; then
# Old
if [[ '$1' == ${all_dates[$j]} ]]; then
# New
if [[ "'$1'" == "${all_dates[$j]}" ]]; then

Я мог пропустить один или несколько экземпляров.

Без кавычек скрипт может «удивиться» параметрами, именами файлов со спецсимволами и т.д.

person dash-o    schedule 29.11.2019
comment
Здравствуйте, спасибо за ответ, я попробую ваши предложения. Что касается вашего вопроса выше Where are the $1 and $2 , я предоставляю их в качестве аргументов из командной строки, например: ./test.sh '2016-03-04' '2016-05-25' здесь agrument1 = 2016-03-04 и argument2=2016-05-25 - person Mihai; 29.11.2019
comment
Спасибо, что поделился. Я думаю, вы получите много информации, добавив в скрипт 'set -x'. По крайней мере, рассмотрите возможность обмена именем файла, который был обработан во время ошибки, и ошибочным номером строки. - person dash-o; 29.11.2019
comment
Я поставил кавычки, как вы предложили, а также добавил set -x , чтобы напечатать дополнительную информацию. Все работает нормально до оператора for, он выполняет все итерации до 2016-04-08. В этот момент генерируется -sh: line 22: 2016-04-08 value too grate for base (error token is "08"). Это строка 22, потому что я добавил также set-x, но здесь я не обновил ее. - person Mihai; 02.12.2019
comment
@mihai Подумайте о том, чтобы поделиться последними несколькими строками вывода '-x', включая сообщение об ошибке В ВОПРОСЕ, ТАК ЧТО участники не могут угадать, что у вас на экране! - person dash-o; 02.12.2019
comment
Хорошо, вот вывод последних нескольких строк (для облегчения чтения я разделил строки с помощью **): ** + for i in '${all_dates[@]}' ** ** 2016-04-08 ** ** + echo 2016-04-08 ** ** -sh: line 22: 2016-04-08: value too great for base (error token is "08") ** - person Mihai; 02.12.2019
comment
Запускаете ли вы скрипт, как указано в вопросе - вывод после «for» должен был быть echo " Index is .... Кроме того, ПОЖАЛУЙСТА, опубликуйте больше вывода, правильно отформатированного для вопроса. Больно (и долго) расшифровывать комментарии. Другие участники SO не будут иметь доступа к этой информации. - person dash-o; 02.12.2019
comment
Извините за мои плохие навыки публикации :(( Я обновил пост, постарался предоставить всю информацию! - person Mihai; 02.12.2019
comment
Благодарю вас! Вы мне очень помогли. И еще раз прошу прощения за мой плохой способ публикации. - person Mihai; 02.12.2019

Прочитав больше, я не нашел способа изменить восьмеричную базу для моего случая. Решение состоит в том, чтобы удалить начальный 0 из месяца и дня, чтобы иметь этот формат 2016-4-8. Я сделал это, используя sed и изменив строку № 10 из моего кода на эту all_dates=($(ls | grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}" | sed -e 's/-0/-/g')).

Также чтение этого поста помогло мне значение слишком велико для базы (токен ошибки 09)

person Mihai    schedule 02.12.2019