The Dutchman
The Dutchman

Reputation: 131

Use bash variable in mongo eval command to insert data

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.

Upvotes: 2

Views: 1487

Answers (1)

randomir
randomir

Reputation: 18697

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

Upvotes: 1

Related Questions