0

I have a problem in the bash script from below.

I'm RUNNING THE CODE AS IT IS POSTED HERE

Code of my bash script:

#! /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

This is the output of the code from above:

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")

Also the structure of my array elements is YYYY-MM-dd The error appear in for statement, hence the need to change the base (from octal to decimal). I have had several attempts, I think this one is the closest to the solution but I didn't suceed:

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

Any help is welcome!

Mihai
  • 29
  • 8
  • Just use `bc` instead. – stephanmg Nov 28 '19 at 13:43
  • @stephanmg I tried but the result is the same. Maybe I used it in a wrong way. How do you suggest to use it ? – Mihai Nov 28 '19 at 13:51
  • `echo "obase=10; ibase=8; OCTAL NUMBER HERE" | bc` converts from octal to decimal. – stephanmg Nov 28 '19 at 14:15
  • 1
    I'm afraid I cannot reproduce the error with any versions of `bash` at hand. The string `2016-04-08` should be harmless as long as it is treated as a string. It may cause an error when used in an arithmetic context including an index of an array, but I cannot find such a usage in your posted code. Does the posted code actually cause the mentioned error, or haven't you simplified your code to ask a question? BR. – tshiono Nov 29 '19 at 00:54
  • @tshiono Hello. At this moment this is my code, I plan to implement other functionalities but since this part of the code produces problems I have to solve it. I'm running the script local on VirtualMachine with Ubuntu 16.04 and go remote on QTS server. I tested locally and it worked perfectly, the problem arises when I use remote. The structure of folder names is like this : ' Asrgv_Image_G_2016_04_08_20_24_33 ' ad i m extracting only the date and operate with it. – Mihai Nov 29 '19 at 07:31
  • 1
    Hmm.. There are several reasons I'm in doubt the posted code and your code are *not* identical. 1) The posted code has an odd `shebang` line at the beginning. 2) I've tested the code on qnap remote server which works well. 3) You mention the folder name is something like `Asrgv_Image_G_2016_04_08_20_24_33` and you are `extracting` only the date but the posted code just tests matching of the string *without* `extracting` it. 4) The posted code expects the date string is separated by dash `-` while the folder name in your comment is separated by underscore `_` as above. I'm totally puzzled.. – tshiono Nov 29 '19 at 07:59
  • @tshiono . Oh now I m comparing and i missed something i will add in initial post sorrySorry I did a mistake the structure is like this `Asrgv_Image_G_2016-04-08-20-24-33 ` . The extraction of `2016-04-08` is happening at this line `all_dates=($(ls | grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}"))` and this is will make my array `all_dates` and the elements of the array are like this ` 2016-03-15 2016-03-18' and so on. – Mihai Nov 29 '19 at 08:09
  • @tshiono Ok I updated. I missed `j=0 and s=0` also the part after the comment `# compare the dates` , and the `shebang` from `!#` to `#!` Thanks you are genius :D Now the post is the same as in my VM machine. – Mihai Nov 29 '19 at 08:27
  • Thank you for the update. Understood about the `extraction`. But your updated script still works with no problem. What if you copy&paste the posted code and try to execute it? I suppose the code itself and the folder names in the server are sufficient to reproduce the error, right (excluding the built-in Linux commands in the server, of course)? – tshiono Nov 29 '19 at 09:17
  • BTW if I modify the line `if [[ '$1' == ${all_dates[$j]} ]]; then` into `if [[ '$1' -eq ${all_dates[$j]} ]]; then`, it causes the mentioned error: `value too great for base`. – tshiono Nov 29 '19 at 09:20
  • As far as I know the output generated by `==` should not be different from `-eq` . – Mihai Nov 29 '19 at 09:56
  • OK I tried the you'r sugestion with to copy the code but I got the same error. One IMPORTANT mention in the 3rd line after `for` statement isntead of `${all_dates[@]}` should be `${all_dates[$i]}`. I will update now. I just saw now if there is `${all_dates[@]}' will not generate the error. – Mihai Nov 29 '19 at 10:16
  • 1
    Consider running the remote script with -x, and sharing the output (insert 'set -x' line before the initial 'cd'). Also, where are $1, $2 ? – dash-o Nov 29 '19 at 10:29
  • @tshiono Thank you for your help , you'r great ! Have a good day! – Mihai Dec 02 '19 at 09:18

2 Answers2

1

As a general rule, always quote any variable that goes into '[[' or '[' condition, unless you are able to guarantee that the value does not have any special value. In this case, this applies to anything that refer to $1, $2 or if 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

I might have missed a one or more instances.

Without quotes, the script may be 'surprised' by parameters, file names with special characters, etc.

dash-o
  • 13,723
  • 1
  • 10
  • 37
  • Hello Thanks for response I will try your suggestions. Regarding to your question from above `Where are the $1 and $2` , I provide them as argumensts from comand line as example: `./test.sh '2016-03-04' '2016-05-25'` here `agrument1 = 2016-03-04` and `argument2=2016-05-25` – Mihai Nov 29 '19 at 11:09
  • Thanks for sharing. I think you will get lot of information from adding 'set -x' to the script. At least, consider sharing the name of the file that was processed at the time of the error, and the erroneous line number – dash-o Nov 29 '19 at 11:51
  • I put quotation marks as you suggested, also add `set -x ` that print more information. Everything works fine until the `for` statement, he do all the iterations until `2016-04-08`. At that point generates `-sh: line 22: 2016-04-08 value too grate for base (error token is "08")`. Is line 22 because I added also `set-x` but here I didn't update it. – Mihai Dec 02 '19 at 06:33
  • 1
    @mihai Consider sharing the the last few lines of the '-x' output, including the error message IN THE QUESTION SO contributors can not guess what is on your screen ! – dash-o Dec 02 '19 at 06:39
  • Ok here is the output of the last few lines (I made a line delimitation using ** for easier reading): ** `+ 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")` ** – Mihai Dec 02 '19 at 06:44
  • 1
    Are you running the script as posted in the question - the output after 'for` should have been `echo " Index is ...`. Also, PLEASE - post more output, formatted properly to the question. It's painful (and time consuming) to decode the comments. Other SO contributors will not have access to this information. – dash-o Dec 02 '19 at 07:35
  • Sorry for my poor skills of posting :(( I updated the post, I tried to provide all the information ! – Mihai Dec 02 '19 at 08:19
  • Thank you! You helped me alot. And I m sorry again for my bad way of posting. – Mihai Dec 02 '19 at 09:20
0

After reading more I don't find a way to change the octal base for my case. The solution is to delete the leading 0 from month and day to have this format 2016-4-8. I did this using sed and changing line nr.10 from my code with this one all_dates=($(ls | grep -oE "[0-9]{4}-[0-9]{2}-[0-9]{2}" | sed -e 's/-0/-/g')).

Also reading this post helped me Value too great for base (error token is "09")

Mihai
  • 29
  • 8