2

I'm not an expert, but all I'm trying to do is run a command line command, get the numbers from it, put them in an array, and insert them into a mongo database with the eval option.

#!/bin/bash

results="$(speedtest-cli --simple | grep -o '[0-9]*')"
echo "${results[@]}"
mongo localhost:27017/ding --eval "db.lloll.insert({date:new Date(),resu:{ping:["${results[0]}","${results[1]}"],down:["${results[2]}","${results[3]}"],uplo:["${results[4]}","${results[5]}"]}})"

This is what I'm running, and everytime I run into the error:

SyntaxError: missing } after property list

But when I run it and insert the data using a hardcoded array it works and I don't understand why.

3
  • Are you trying to quote the array expansions, or deliberately turning off the quotes to expand them? Commented Dec 7, 2017 at 16:11
  • Use shellcheck for syntax errors : here, you should escape your inner quotes. Commented Dec 7, 2017 at 16:12
  • Try using single quotes as the inner quotes instead. In Javascript both double and single quotes can be used as string delimiters (mongo uses js as the query language). Commented Dec 7, 2017 at 16:14

1 Answer 1

1

Without going into the details of how you extract the numbers of interest from speedtest-cli output (speedtest-cli on my system maybe has different output than on your system; numbers include decimal point you don't grep), the problem is with splitting those numbers -- i.e. you don't explicitly store them into an array. You should try with array=(e1 e2 ..) construct:

results=( $(speedtest-cli --simple | grep -o '[0-9]*') )

or with declare -a:

declare -a results=$(speedtest-cli --simple | grep -o '[0-9]*')

If you don't store the result into an array, you can not index the numbers with ${results[i]}, as you are trying to do. Namely, what you are running right now with --eval is:

"db.lloll.insert({date:new Date(),resu:{ping:[46 677 9 18 0 07,],down:[,],uplo:[,]}})"

Note the obvious syntax error due to ${results[0] containing all the numbers separated with space, instead of only the first number. But when you use the array, you get something like:

"db.lloll.insert({date:new Date(),resu:{ping:[46,677],down:[9,18],uplo:[0,07]}})"

Your

echo "${results[@]}" 

has provided you with a clue -- it outputs one number per line (due to the quoting, newlines were preserved):

$ echo "${results[@]}"
46
677
9
18
0
07

while if the results was really an array (as expected), the elements would have been joined on the first character in IFS, which is a space by default:

$ echo "${results[@]}"
46 677 9 18 0 07

A safer (or more robust) way of inspecting the value of a variable is with declare -p:

$ declare -p results
declare -a results='([0]="46" [1]="677" [2]="9" [3]="18" [4]="0" [5]="07")'
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, it works now! And I clearly still have a lot to learn. I used the method you described to really store the numbers in the array and it works now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.