How can I insert a document from a bash script to mongodb? - bash

What is the exact code I need to execute, to insert a document into a mongodb using bash. At the moment I am able to look documents in mongodb via bash script up, but inserting does not work.

You can inject javascript code from a javascript file:
mongo 127.0.0.1/MyDatabase script.js
with script.js:
var document = {
name : "document_name",
title : "document_title"
};
db.MyCollection.insert(document);
or directly:
mongo 127.0.0.1/MyDatabase --eval 'var document = { name : "document_name", title : "document_title" }; db.MyCollection.insert(document);'

If you don't want to serve script from a file (I try not to source external files as much as possible) or not use --eval option which can be difficult to read if you have many entries, you can use a bash heredoc
You can type in terminal:
-bash-4.1$ mongo mongodb://myServerAddress/myDbName <<EOF
> db.myCollectionName.insert({
> name: "doc name",
> title: "doc title"
> })
> EOF
Result:
MongoDB shell version v3.4.1
connecting to: mongodb://myServerAddress/myDbName
MongoDB server version: 3.0.7
WARNING: shell and server versions do not match
WriteResult({ "nInserted" : 1 })
bye
-bash-4.1$
If you want to keep it in a script, just remove > which is actually prompt for a multiline command.
For in-script use, it should be as below:
#!/usr/bin/env bash
mongo mongodb://myServerAddress/myDbName <<EOF
db.myCollectionName.insert({
name: "doc name",
title: "doc title"
})
EOF

insert some JSON into Mongo DB sample_db, collection products_coll
echo '{ item: "card", qty: 115 }' | \
sed 's#^#db.products_coll.insert( #; s#$# ) #' | mongo sample_db
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017/sample_db
MongoDB server version: 3.6.3
WriteResult({ "nInserted" : 1 })
bye
make sure it is here
mongoexport -d sample_db -c products_coll
{"_id":{"$oid":"5d27e83152a049227799710e"},"item":"card","qty":115.0}

Related

Proper way to directly pass yaml content to kubectl patch?

Example of functional kubectl patch command:
# kubectl patch storageclass local-path \
-p '{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class": "false"}}}'
In certain cases the patched key/values are too numerous, so is recommended to use a file instead:
# kubectl patch storageclass local-path --patch-file=file.yaml
I would like to use an alternative of this format, which returns an error:
cat << 'EOF' | kubectl patch storageclass local-path --patch-file -
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: false
EOF
error: unable to read patch file: open -: no such file or directory
My goal is to use a dynamic way of pushing the patch data, without creating a file. What would be the correct format? Thank you.
Update: Based on provided documentation, I tried this format:
cat << 'EOF' | kubectl patch storageclass local-path --type=merge -p -
{
"metadata": {
"annotations": {
"storageclass.kubernetes.io/is-default-class": "false"
}
}
}
EOF
Error from server (BadRequest): json: cannot unmarshal array into Go value of type map[string]interface {}
Or:
kubectl patch storageclass local-path --type=merge -p << 'EOF'
{
"metadata": {
"annotations": {
"storageclass.kubernetes.io/is-default-class": "false"
}
}
}
EOF
error: flag needs an argument: 'p' in -p
What would be the correct format? I'm trying to avoid a very long line and keep a nice readable format.
If you look at the documentation of kubectl patch help that it is not a supported feature to pass the patch as you are trying to do because you either need to pass the patch as a json or from the file contains that contians the data.
You can pass something like this, but still you need to clean up the file you created here (auto.yaml).
$ cat <<EOF | echo "metadata:
> labels:
> app: testapp "> auto.yaml | kubectl patch pod pod-name --patch-file=auto.yaml
> EOF
For more information about EOF refer to the Here Document section in this document
For Updated question:
You are actually missing the ' quotation before starting the json and don't give - after -p. Give a try like this, this is working in our environment
$ cat <<EOF | kubectl patch deployments nginx --type=merge --patch '{
> "metadata":
> {
> "labels":
> {
> "check": "good"
> }
> }
> }'
> EOF

Import bash script as UserData in AWS CFN template using Troposphere

I am trying to create an AWS template using Troposphere and I am stuck at a point where I have to use my Bash Script as UserData. My main problem being Ref used in Bash Script. I am importing Bash Script as a file read and encode them to Base64 as:
UserData= Base64(Join("", [
open('path to my bashscript', "r")
.read()
.splitlines(True)
]))
My bash script has Ref used as:
#!/bin/bash
set -x
export -f check_instance_service_status
timeout Ref('ValueReferenced') bash -c "check_instance_service_status $ELB_NAME"
The output I am getting is:
"#!/bin/bash\n",
"set -x\n",
"\n",
" export -f check_instance_service_status\n",
" timeout Ref('ValueReferenced') bash -c \"check_instance_service_status $ELB_NAME\"\n",
" RC=$?\n",
However, I want the Ref to be converted to proper JSON compatible as:
" timeout \"",
{
"Ref": "ValueReferenced"
},

Sort command in bash script does not work when called from Jenkins

I am trying to execute a shell script on a windows node using Jenkins.
The bash script uses sort -u flag in one of the steps to filter out unique elements from an existing array
list_unique=($(echo "${list[#]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
Note - shebang used in the script is #!/bin/bash
On calling the script from command prompt as - bash test.sh $arg1
I got the following error -
-uThe system cannot find the file specified.
I understand the issue was that with the above call, sort.exe was being used from command prompt and not the Unix sort command. To get around this I changed the path variable in Windows System variables and moved \cygwin\bin ahead of \Windows\System32
This fixed the issue and the above call gave me the expected results.
However, When the same script is called on this node using Jenkins, I get the same error again
-uThe system cannot find the file specified.
Jenkins stage calling the script
stage("Run Test") {
options {
timeout(time: 5, unit: 'MINUTES')
}
steps {
script {
if(fileExists("${Test_dir}")){
dir("${Test_dir}"){
if(fileExists("test.sh")){
def command = 'bash test.sh ${env.arg1}'
env.output = sh(returnStdout: true , script : "${command}").trim()
if (env.output == "Invalid"){
def err_msg = "Error Found."
sh "echo -n '" + err_msg + " ' > ${ERR_MSG_FILE}"
error(err_msg)
}
sh "echo Running tests for ${env.output}"
}
}
}
}
}
}
Kindly Help

MongoDB run query from terminal

I'm try run bash script from terminal (Ubuntu 14.04), but i'm get error:
$ ../scripts/for_webapp/init_devices_limit.sh
db.company.update({"_id": NumberInt(777)}, {$set: {"devices_limit": NumberInt(-1)}}, {"multi":true});
MongoDB shell version: 3.2.5
connecting to: localhost:27017/statistic
2016-04-22T12:37:01.366+0500 E QUERY [thread1] SyntaxError: expected expression, got end of script #(shell eval):1:25
Script:
#!/usr/bin/env bash
: ${DBHOST:=localhost}
: ${DBPORT:=27017}
: ${DBNAME:=statistic}
: ${COMPANY_ID:=777}
: ${INIT_VALUE:=-1}
QUERY='db.company.update({"_id": NumberInt('$COMPANY_ID')}, {$set: {"devices_limit": NumberInt('$INIT_VALUE')}}, {"multi":true});'
echo $QUERY
mongo $DBHOST:$DBPORT/$DBNAME --eval $QUERY
I'm solve this with using EOF input signal (without use --eval argument).
#!/usr/bin/env bash
: ${DBHOST:=localhost}
: ${DBPORT:=27017}
: ${DBNAME:=statistic}
: ${COMPANY_ID:=777}
: ${INIT_VALUE:=-1}
QUERY='db.company.update({"_id": NumberInt('$COMPANY_ID')}, {$set: {"devices_limit": NumberInt('$INIT_VALUE')}})'
echo $QUERY
# mongo $DBHOST:$DBPORT/$DBNAME --eval $QUERY
# don't use --eval
mongo $DBHOST:$DBPORT/$DBNAME <<_EOF_
$QUERY
_EOF_

MongoDB - escaping quotes while inserting record

I have encountered a strange problem while I was trying to write a bash scritp to copy some data from one database to another.
To make things simple I will present the issue with the following example:
Let's say, we have a file in which are mongo insert commands that want to execute in mongo client. With Bash it will be:
cat file.json | mongo --verbose --host $HOST
This works fine until we use qoutes in records content.
For example:
use somedb;
db["collection"].insert({ "field": "test" })
#This of course works
db["collection"].insert({ "field": "test \" test" })
#But this doesn't
db["collection"].insert({ "field": "test \\" test" }) "#<-For syntax coloring
#I thounght maybe double quoting will help, but this also doesn't work
db["collection"].insert({ "field": "\"test\"" })
#This SUPRISINGLY works!!!
My question is, what is the propper way of escaping quotes for mongo client (I am using MongoDB shell verions: 2.2.4)?
Why when there is an even number of quotes in record, the script will succeed and with odd number will fail?
I will add that, there are no error messages. Mongo just fails silently(even with --verbose) and no new records appears in collection.
There's a JIRA ticket for this issue and it's fixed in 2.5.0.
For now, you can use the unicode point for double quote when inserting:
> db.foo.insert({ "field": "test \u0022 test" })
> db.foo.find()
{ "_id" : ObjectId("533455e563083f9b26efb5c2"), "field" : "test \" test" }

Resources